Le langage Java reprend en grande partie lasyntaxe du langageC++. Néanmoins, Java est épuré des concepts les plus subtils du C++ et à la fois les plus déroutants, tels que lespointeurs et références, ou l’héritage multiple contourné par l’implémentation desinterfaces. De même, depuis la version 8, l'arrivée des interfaces fonctionnelles introduit l'héritage multiple (sans la gestion des attributs) avec ses avantages et inconvénients tels que l'héritage en diamant. Les concepteurs ont privilégié l’approcheorientée objet de sorte qu’en Java, tout est objet à l’exception destypes primitifs (nombres entiers,nombres à virgule flottante, etc.) qui ont cependant leurs variantes qui héritent de l'objet Object (Integer, Float, Double, etc.).
Java permet de développer des applicationsclient-serveur. Côté client, lesapplets sont à l’origine de la notoriété du langage. C’est surtout côté serveur que Java s’est imposé dans le milieu de l’entreprise grâce auxservlets, le pendant serveur des applets, et plus récemment lesJavaServer Pages (JSP) qui peuvent se substituer àPHP,Active Server Pages (ASP) etASP.NET.
Le langage Java est issu d’un projet de Sun Microsystems datant de 1990 : l’ingénieur Patrick Naughton n’était pas satisfait par le langage C++ utilisé chez Sun, sesinterfaces de programmation en langage C, ainsi que les outils associés. Alors qu’il envisageait une migration versNeXT, on lui proposa de travailler sur une nouvelle technologie et c’est ainsi que leProjetStealth (furtif) vit le jour.
LeProjetStealth fut rapidement rebaptiséGreen Project avec l’arrivée deJames Gosling et de Mike Sheridan. Ensemble, aidés par d’autres ingénieurs, ils commencèrent à travailler dans un bureau de la rue Sand Hill àMenlo Park enCalifornie. Ils essayèrent d’élaborer une technologie pour le développement d’applications d’une nouvelle génération, offrant à Sun la perspective d’opportunités uniques[6].
L’équipe envisageait initialement d’utiliser le langage C++, mais l’abandonna pour différentes raisons. Tout d’abord, ils développaient sur unsystème embarqué avec des ressources limitées et estimaient que l’utilisation du C++ demandait un investissement trop important et que cette complexité était une source d’erreur pour les développeurs. L'absence deramasse-miettes impliquait que la gestion de la mémoire devait être programmée manuellement, un défi mais aussi une source d’erreurs[6].
L’équipe était également insatisfaite des lacunes du langage C++ au niveau de la sécurité, de la programmation distribuée, dumulti-threading. De plus, ils voulaient une plateforme qui puisse être portée sur tout type d’appareils ou de plateformes[6].
Bill Joy avait envisagé un nouveau langage combinant le meilleur du langage de programmationMesa(en) et dulangage C. Dans un article appeléPlus loin (Further), il proposa à Sun que ses ingénieurs développent un environnement orienté objet basé sur le langage C++. À l’origine, Gosling envisageait de modifier et d’améliorer le langage C++, qu’il appelait C++ ++ --, mais l’idée fut bientôt abandonnée au profit du développement d’un nouveau langage de programmation qu’ils appelèrentOak (chêne) en référence, selon la légende, à un arbre planté devant la fenêtre de leur bureau[réf. souhaitée].
À l’été 1992, ils furent capables de faire une démonstration constituée d'uneplateforme incluant le système d’exploitation Green[réf. souhaitée], le langage Oak (1992), les bibliothèques et le matériel. Leur première réalisation, présentée le, fut la construction d’unPDA appeléStar7 ayant uneinterface graphique et unagent intelligent appeléDuke pour prêter assistance à l’utilisateur[6].
En novembre de la même année, leGreen Project fut abandonné pour devenirFirstPerson, Inc, appartenant en totalité à Sun Microsystems et l’équipe fut relocalisée à Palo Alto. L’équipeFirstPerson était intéressée par la construction d’outils hautement interactifs et quand Time Warner publia un appel d’offres en faveur d’un décodeur multifonctions, FirstPerson changea d’objectif pour proposer une telle plateforme.
Cependant, l’industrie de latélévision par câble trouva qu’elle offrait trop de possibilités à l’utilisateur et FirstPerson perdit le marché au profit deSilicon Graphics. Incapable d’intéresser l’industrie audiovisuelle, la société fut réintégrée au sein de Sun.
De juin à, après trois jours de remue-méninges avec John Gage, James Gosling, Joy, Naughton, Wayne Rosing etEric Schmidt, l’équipe recentra la plateforme sur leweb. Ils pensaient qu’avec l’avènement du navigateurMosaic, Internet était le lieu où allait se développer le même genre d’outil interactif que celui qu’ils avaient envisagé pour l’industrie du câble. Naughton développa comme prototype un petit navigateur web, WebRunner qui deviendra par la suiteHotJava[6].
Le nom« Java » n'est pas unacronyme, il a été choisi lors d'unbrainstorming[7] en remplacement du nom d'origine« Oak », à cause d'un conflit avec une marque decarte vidéo, parce que le café (« java » en argot américain)[8] est la boisson favorite de nombreux programmeurs[9]. Le logo choisi par Sun est d'ailleurs une tasse de café fumant.
En, HotJava et la plateforme Java furent présentés pourSun Executives. Java 1.0a fut disponible en téléchargement en 1994 mais la première version publique du navigateur HotJava arriva le à la conférenceSunWorld[10].
L’annonce fut effectuée par John Gage, le directeur scientifique de Sun Microsystems. Son annonce fut accompagnée de l’annonce surprise de Marc Andressen, vice-président de l’exécutif deNetscape que Netscape allait inclure le support de Java dans ses navigateurs. Le, le groupe Javasoft fut constitué par Sun Microsystems pour développer cette technologie[11]. Deux semaines plus tard la première version de Java était disponible.
L'apparition de la version 1.2 du langage marque un tournant significatif : c'est en 2000 qu'apparait simultanément la déclinaison en deux plateformes Java :
Java 2 Standard Edition (J2SE), plateforme avec les API et bibliothèques de bases, devenue depuisJava SE ;
Java 2 Enterprise Edition (J2EE), extension avec des technologies pour le développement d'applications d’entreprise, devenueJava EE.
Sun les qualifie alors de plateformeJava 2 par opposition aux premières générations 1.0 et 1.1. Toutes les versions ultérieures, de J2EE 1.2 à Java SE ou Java EE 7 restent désignées sous le qualificatif de plateformes Java 2, bien que le '2' ait été depuis officiellement abandonné.
Les applets sur le poste Client peuvent communiquer avec desservlets sur le Serveur, tout comme Javascript peut communiquer avec le Serveur au moyen d’AJAX.Flex utilise quant à lui la technologie Flash par le biais duAdobe Flash Player.
À une époque oùJavaScript souffrait de problèmes de compatibilité inter-navigateurs, les applets Java avaient l'avantage de la portabilité car le portage d'interfaces complexes était difficile à assurer pour tous les navigateurs du marché.
Outre la retombée de la « mode » Java, les progrès faits dans les technologies concurrentes à Java ont amené la plupart des développeurs à se détourner des applets Java et des problèmes inhérents à cette technologie (incompatibilités entre les JVM, mauvaises performances, pauvreté desbibliothèques graphiques, complexité). Enfin, les navigateurs modernes n'incluent plus systématiquement l'environnement Java à cause de sa taille importante, et le taux de machines capables d'afficher des applets n'était plus que de 70 % en 2010, bien plus faible que pour Flash par exemple[12]. En 2010, la quasi-totalité des applications clients riches utilisent des technologies alternatives ; Flash pour l'essentiel mais aussiGWT.
Enfin, l'arrivée deHTML5, destiné à embarquer de nombreuses fonctionnalités RIA etmultimédia, rend également les applets caducs.
JavaFX
Avec l'apparition de Java 8 en,JavaFX devient l'outil de création d'interface graphique ('GUItoolkit') officiel de Java, pour toutes les sortes d'application (applications mobiles, applications sur poste de travail, applications Web…), le développement de son prédécesseur Swing étant abandonné (sauf pour les corrections de bogues). JavaFX est une pure API Java (lelangage de script spécifique qui lui a été un temps associé est maintenant abandonné). JavaFX contient des outils très divers, notamment pour les médias audio et vidéo, le graphisme 2D et 3D, laprogrammation Web, laprogrammation parallèle, etc.
Avec lesserveurs d’applications, on utilise desEJB pour encapsuler les classes définies précédemment. Ces éléments sont utilisés dans des architecturesJ2EE pour des applications multicouches.L'avantage qu'on tire de ce travail est de pouvoir cacher au client l'implémentation du code côté serveur.
L’utilisation native du langage Java pour des applications sur un poste de travail restait jusqu'à présent relativement rare à cause de leur manque de rapidité. Cependant, avec l’accroissement rapide de la puissance des ordinateurs, les améliorations au cours des années 2000, de la machine virtuelle Java et de la qualité des compilateurs, plusieurs technologies ont gagné du terrain commeNetBeans et l’environnementEclipse, les technologies de fichiers partagésLimeWire,Vuze (ex Azureus), etI2P. Java est aussi utilisé dans le programme de mathématiquesMATLAB, au niveau de l’interface homme machine et pour lecalcul formel. Les applicationsSwing apparaissent également comme une alternative à la technologie .NET.
Oracle annonce début à la conférence JavaOne sa volonté de proposer des solutions Java pour le domaine des logiciels embarqués, pour processeurs moins puissants que ceux habituellement disponibles sur les PC. Oracle fédère autour d'elle tout unécosystème d'entreprises spécialistes de ces segments de marchés, comme l'éditeurMicroEJ[13] ou encoreSTMicroelectronics qui propose du Java sur ses STM32[14] dont le cœur est un CortexM3/M4.
Java, notamment viaEclipse etNetBeans, offre déjà des environnements de développement intégrés pour mobile. Java est le principal langage utilisé pour développer des applications pour le système d'exploitation libre pour Mobile deGoogle :Android.
JavaFX peut aussi permettre l'utilisation de Java sur mobiles, bien que ce ne soit pas son objectif principal.
Microsoft a fourni en 2001 un environnement de travail de type Java, dénomméJ++, avec ses systèmes d’exploitation avant la sortie deWindows XP. À la suite d'une décision de justice[réf. nécessaire], et au vu du non-respect des spécifications de ce langage, Microsoft a dû abandonner celui-ci et créer un nouveau langage, de nomC# (cf. chapitre « Indépendance vis-à-vis de la plateforme » plus bas)
Beaucoup de fabricants d’ordinateurs continuent d’inclure un environnement JRE sur leurs systèmes Windows.
Java apparaît également comme un standard au niveau duMac OS X d’Apple aussi bien que pour les distributionsLinux. Ainsi, de nos jours, la plupart des utilisateurs peuvent lancer des applications Java sans aucun problème.Toutefois, sur ordinateur Apple, la distribution de Java 5 à Java 6 fut assurée directement par Apple, et non par Oracle[15]. Cette politique entraîna des retards et des restrictions de version :
Ainsi J2SE 1.4 ne fut pas disponible avantMac OS X v10.2 (nom de codeJaguar), J2SE 5.0 à partir deMac OS X v10.4 (Tiger), Java SE 6 fonctionne uniquement sousMac OS X v10.5 (Leopard) équipé de processeurIntel[16], et Java 7 exige un ordinateur Mac Intel exécutant la versionMac OS X v10.7.3 (Lion).
Le, Sun Microsystems annonce le passage de Java, c’est-à-dire leJDK (JRE et outils de développement) et les environnements Java EE (déjà sous licence CDDL) et Java ME sous licenceGPL d’ici, sous le nom de projetOpenJDK[18].
En, Sun publie effectivement OpenJDK sous licence libre. Cependant OpenJDK dépend encore de fragments de code non libre que Sun ne détient pas. C'est pourquoi la sociétéRedhat lance en le projetIcedTea(en) qui vise à remplacer les fragments de code non libre et ainsi rendre OpenJDK utilisable sans aucunlogiciel propriétaire. En, le projet IcedTea a passé les tests rigoureux de compatibilité Java (TCK)[19].IcedTea est donc une implémentation open-source des spécifications de Java. Sun, puis Oracle, garde toutefois le contrôle de la technologie par le biais d'un catalogue de brevets s'appliquant à Java, ainsi que par le maintien du TCK sous une licence propriétaire.
La sociétéOracle a acquis en 2009 l'entrepriseSun Microsystems. On peut désormais voir apparaître le logo Oracle dans les documentations de l'api Java.
Le,James Gosling, le créateur du langage de programmation Java, démissionne d’Oracle pour des motifs qu’il ne souhaite pas divulguer. Il était devenu le directeur technologique de la division logicielle client pour Oracle.
En 2018, Oracle annonce que les mises à jour de sa version Java SE 8 pour un usage professionnel seraient soumis à unelicence payante à partir de[20].
En 2023, Oracle modifie en profondeur son mode de licence pour Java SE, en ne proposant plus les licences au processeur ou à l'utilisateur nommé, mais uniquement au nombre total d'employés de l'entreprise concernée, y compris ceux qui n'utilisent pas Java[21], ce qui risque d'augmenter significativement le coûts[22] et provoque des réactions négatives parmi les entreprises concernées[23].
Le langage Java a connu plusieurs évolutions depuis le JDK 1.0 (Java Development Kit) avec l’ajout de nombreuses classes et packages à la bibliothèque standard. Depuis le J2SE1.4, l’évolution de Java est dirigée par le JCP (Java Community Process) qui utilise les JSR (Java Specifications Requests) pour proposer des ajouts et des changements sur laplateforme Java. Le langage lui-même est spécifié par le JLS (Java Language Specification), les modifications du JLS étant gérées sous le code JSR 901[24].
Il faut noter que les évolutions successives du langage ne portent guère sur sa syntaxe -relativement stable depuis le début- mais principalement sur l'enrichissement de ses fonctions, avec l'embarquement et l'optimisation de bibliothèques logicielles (API) dans des domaines très variés de l'informatique : bases de données, gestionXML, informatique distribuée et web, multimédia, sécurité…
Il faut distinguer la version du langage Java de celles des plateformes et du JRE :
Le numéro majeur de version du langage (par exempleJava 5) spécifiée par le JLS, est ainsi lenuméro mineur pour le JRE ou la plateforme (par ex JRE 1.5 ou Java SE 1.5)[25] ;
Le JRE et la plateforme Java SE sont eux identifiés depuis Java 5 par un même numéro de version : ainsi Java SE 1.6.0.43, et le JRE 1.6.0.43, sont tous deux conformes au langage Java 6, mais ont fait l'objet notamment decorrectifs de sécurité[26] ;
Java FX (orientéRIA), constitué essentiellement d'un sous-ensemble de JavaSE, suit également le même numéro de version : Java FX en est ainsi sa version 2.7 pour 1.7[27](également compatible JRE 1.6) ;
En revanche, les plateformesEnterprise Edition (Java EE) etMobile Edition (Java ME) sont identifiées par le numéro de version de leur propreSDK ; ainsi début 2013 :
Java EE en était encore à la version 6 (Java EE 6 SDK Update 4), mais fonctionnait avec les JDK 6 ou 7[28]; il n'est réellement passé à Java 7 que mi-[29],
Deux versions peuvent parfois être proposées simultanément, telles que 8u65 & 8u66 : la différence consiste généralement en des corrections de bugs mineurs (sans incidence de sécurité notamment), pour lesquelles la mise à jour à la toute dernière version n'est pas critique et est de ce fait laissée au choix des administrateurs (JRE) ou développeurs (JDK).
Les versions publiques de Java peuvent être suivies de versions non publiques, dites Advanced, réservées à des usages commerciaux ; ainsi Java 1.6u45 est la dernière version publique de Java6, mais 6u113 l'ultime version disponible fin.
En date du 31/05/2025, les versions LTS (pour Long Term Support) actuelles sont Java 8, 11, 17 et 21[31].
J2SE 1.2 ( - 1 524 classes et interfaces) — Nom de codePlayground. Cette version et les suivantes jusque J2SE 7.0 sont rebaptiséesJava 2 et la version nommée J2SE (Java 2 Platform, Standard Edition) remplace JDK pour distinguer la plateforme de base de la version J2EE (Java 2 Platform, Enterprise Edition) et de la version J2ME (Java 2 Platform, Micro Edition). Plusieurs ajouts[38] dont :
le mot-cléstrictfp (strict floating-point :virgule flottante stricte) ;
JNDI (Java Naming and Directory Interface) inclus de base (disponible auparavant commeextension) ;
JPDA (Java Platform Debugger Architecture).
J2SE 1.4 ( - 2 723 classes et interfaces) — Nom de codeMerlin. Ce fut la première révision de la plateforme sous JCP (Java Community Process)[40]. Les principaux changements[41] sont :
Sortie le (3 270 classes et interfaces), son nom de code estTiger. Elle est initialement numérotée 1.5, qui est toujours utilisé comme numéro de version interne[43]. Développé par(en) JSR 176,Tiger ajoute un nombre significatif de nouveautés[44] au langage :
intégration du composant logicielJava Web Start dans l'environnement d'exécution Java (JRE)[45] ;
metadata — également appelées annotations, permet au langage de construire des classes et des méthodes étiquetées avec des données additionnelles qui peuvent être utilisées en tant que méta-données (Spécifiée dans(en)JSR 175) ;
autoboxing/unboxing — conversion automatique entre des types primitifs (comme le typeint) et le Wrapper de classe correspondant (comme la classe Integer) (Spécifié dans(en)JSR 201) ;
énumérations — le mot-cléenum permet de créer une liste ordonnée de valeurs en gardant lasûreté du typage. Auparavant, ceci pouvait seulement être réalisé par des entiers constants (Spécifié dans JSR 201) ;
varargs — la syntaxeObject… utilisée dans une déclaration de méthode permet de spécifier un nombre variable d’arguments pour cette méthode. C’est un fonctionnement équivalent à la fonction « printf » en C ;
imports statiques — Cette fonctionnalité permet d’utiliser les constantes d’une classe sans spécifier le nom de cette classe et sans passer par « l’anti-pattern Constant Interface » (c’est l’expression utilisée sur le site de Sun) ;
extension dufor pour les boucles — la syntaxe dufor est étendue avec une syntaxe spéciale pour itérer sur n’importe quel objet itérable comme un tableau, ou une collection en utilisant la syntaxe :
Cet exemple parcourt le contenu de l’objet widgets de la classe Iterable et contenant uniquement des références vers des objets de la classe Widget, assignant chacun de ces éléments à la variable w et ensuite appelle la méthode display() sur l’élément w (spécifié dans JSR 201). Une syntaxe similaire sera introduite en 2011 dansC++11.
En plus des changements au niveau du langage, des changements plus importants ont eu lieu au fil des années qui ont conduit des quelques centaines de classes dans le JDK 1.0 à plus de 3 000 dans J2SE 5.0. Des API entières, comme Swing ou Java2D, ont été ajoutées et beaucoup de méthodes de l’original JDK 1.0 ont été déclaréesdeprecated (c’est-à-dire déconseillées, elles pourraient être supprimées dans une version ultérieure de Java).
Sortie le (3 777 classes et interfaces dans plus de 20 paquetages), son nom de code estMustang[46]. Une version bêta est sortie le, une autre bêta en, une version « release candidate » en, et la version finale le. Avec cette version, Sun remplace définitivement le nom J2SE par Java SE et supprime le .0 au numéro de version[47].
Cette version a été l'objet de nombreusesfailles de sécurité et leurs mises à jour correctives, conduisant à la version 1.6.0_45 par Oracle et même 1.6.0_51 pour sa version Mac OS. C'est d'ailleurs là la dernière version de Java fonctionnant pour Mac OS X 10.6 et antérieurs.
Sortie le (8 000[48] classes et interfaces), son nom de code estDolphin. Il s’agit de la première version sous la licenceGNU GPL.
Dès l'update 6 (7u6), l'édition standard Oracle de Java supportant de nouveau pleinement Mac OS X[49], les mises à jour pour cet OS ne sont plus prises en charge par Apple mais par Oracle. Toutefois cette version de Java n'est pas supportée parMac OS X v10.6 : En effet certaines API requises par Java 7 ont bien été incluses par Apple dans Mac OS X 10.7.3, mais il n'est pas prévu qu'elles soient implémentées sur les précédentes versions de Mac OS[50].La version 7u90 d' est la dernière mise à jour de Java 7 disponible publiquement[51].
Java 7 propose entre autres les nouveautés suivantes :
la notation binaire ;
le formatage numérique pour plus de lisibilité ;
les switch avec des string ;
l'inférence des types à la création d'instance pour éviter une redondance de syntaxe (cf.List<String> lst = new ArrayList<>();) ;
le multicatch permettant de concaténer les exceptions catchées via des| ;
java.nio (JSR 203) qui propose notamment une nouvelle interface Path, un système de parcours des répertoires, un service de watch…
les tasks pour paralléliser les calculs jugés trop lourd ou trop coûteux ;
l'autoboxing d'objets vers les types primitifs ;
interface utilisateur : transparence des frames, bordures arrondies, gestion des évènements asynchrones via les secondary loops, les JLayers, les Painters, le nouveau style Nimbus…
Nom de code Kenaï. Diverses releases en cours de développement du JDK sont disponibles au téléchargement dès l'automne 2013[52], et Java 8 sort mi- conformément à unefeuille de route présentée par Oracle dès[53].
Une des nouveautés majeures de cette version est l’ajout deslambdas[54], entraînant une refonte d'une partie de l'API, notamment les collections et la notion destream. Les autres ajouts notables incluent les optionnels, les implémentations par défaut au sein d'une interface, une refonte de l'API date, etc.En revanche la version Enterprise Edition (Java 8 EE) n'est pas attendue avant 2017.
La modularisation de la JVM avec le projetJigsaw, initialement prévue pour cette version, est quant à elle reportée à la version 9[55], du fait notamment des failles de sécurité rencontrées par Java 6 dont Oracle a privilégié la correction en 2013 par rapport aux évolutions de Java.
JEP 354 : (Switch - aperçu v2) Nouveau casecase...-> (case traditionnelcase...:)
switch(nombre){//case traditionnelcase5:System.out.println("La variable est égale à 5");break;//nouveau casecase5->System.out.println("La variable est égale à 5");}
La première caractéristique, le caractère orienté objet (« OO ») et familier, fait référence à une méthode de programmation et de conception du langage et le fait qu'un programme écrit en Java ressemble assez fort à un programme écrit enC++.
Bien qu’il existe plusieurs interprétations de l’expressionorienté objet, une idée phare dans ce type de développement est que les différents types de données doivent être directement associés avec les différentes opérations qu’on peut effectuer sur ces données. En conséquence, les données (appeléesPropriétés) et le code les manipulant (appeléMéthodes) sont combinés dans une même entité appeléeClasse d'objet. Le code devient logiquement découpé en petites entités cohérentes et devient ainsi plus simple à maintenir et plus facilement réutilisable, étant intrinsèquement modulaire.
D’autres mécanismes tels que l’héritage permettent d’exploiter toutes les caractéristiques d’uneClasse précédemment écrite dans ses propres programmes sans même avoir à en connaître le fonctionnement interne — on n’en voit que l’interface (l'interface décrit les propriétés et les méthodes sans fournir le code associé). Java interdit la notion d'héritage depuis plusieurs classes parent sauf si elles sont des interfaces.
Dans la version 1.5 du langage ont été rajoutés lesgénériques, un mécanisme depolymorphisme similaire (mais différent) auxtemplates du langageC++ ou aux foncteurs d’OCaml. Les génériques permettent d’exprimer d’une façon plus simple et plus sûre (du point de vue du typage) les propriétés d’objets comme des conteneurs (listes, arbres…) : le type liste est alors considéré génériquement par rapport au type d’objet contenu dans la liste.
Cet élément contribue à la robustesse et à la performance des programmes, le ramasse-miettes (Garbage Collector) est appelé régulièrement et automatiquement pendant l'exécution du programme. Sur les systèmesmulti-processeurs et/oumulti-cœurs, celui-ci emploie même desthreads multiples à faible priorité afin de perturber le moins possible l'exécution du programme[82]. En outre, le programmeur peut au besoin suggérer de lancer le ramasse-miettes à l’aide de la méthodeSystem.gc().
Un grief récurrent à l’encontre de langages comme C++ est la lourde tâche d’avoir à programmer manuellement la gestion de la mémoire. En C++, la mémoire allouée par le programme pour créer un objet est désallouée lors de la destruction de celui-ci (par exemple par un appel explicite à l'opérateurdelete). Si le programmeur oublie de coder la désallocation, ceci aboutit à une « fuite mémoire », et le programme en consomme de plus en plus. Pire encore, si par erreur un programme demande plusieurs fois une désallocation, ou emploie une zone de mémoire après avoir demandé sa désallocation, celui-ci deviendra très probablement instable et causera une erreur fatale.
En Java, une grande partie de ces problèmes est évitée grâce auramasse-miettes. L'espace mémoire nécessaire à chaque objet créé est géré dans un tas de mémoire (enanglais :memory heap) réservé à cet usage. Le programme accède à chaque objet via une référence dans le tas. Quand il n'existe plus aucune référence permettant d'atteindre un objet, le ramasse-miettes le détruit automatiquement — puisqu'il est devenu inaccessible — libérant la mémoire et prévenant ainsi toute fuite de mémoire.
Le ramasse-miettes emploie un algorithme de marquage puis libération (enanglais :mark and sweep[82]) qui permet de gérer les cas complexes d'objets se référençant mutuellement ou de boucles de références (cas d'uneliste à chaînage double par exemple). En pratique, il subsiste des cas d'erreur de programmation où le ramasse-miettes considère qu'un objet est encore utile alors que le programme n'y accède plus fonctionnellement (mais garde une référence sur l'objet), ce qui constitue un cas particulier de « fuite mémoire ».
Le ramasse-miettes rend sensiblement plus simple et plus sûre la gestion de la mémoire. Les concepteurs et les utilisateurs de programmes ou bibliothèques (en anglaisLibraries) n'ont pas à se soucier de la désallocation des objets (opérateurdelete en C++), sauf éventuellement pour des raisons de performance.
L’indépendance vis-à-vis de la plateforme signifie que les programmes écrits en Java fonctionnent de manière parfaitement similaire sur différentesarchitectures matérielles. La licence de Sun pour Java insiste ainsi sur le fait que toutes les implémentations doivent être compatibles. On peut ainsi théoriquement effectuer le développement sur une architecture donnée et faire tourner l’application finale sur toutes les autres.
Ce résultat est obtenu par :
des bibliothèques standard fournies pour pouvoir accéder à certains éléments de la machine hôte (le graphisme, le multithreading, la programmation réseau…) exactement de la même manière sur toutes les architectures ;
des compilateurs Java qui compilent le code source « à moitié » afin d’obtenir unbytecode (plus précisément lebytecode Java, un langage de typeassembleur, proche de la machine virtuelle et spécifique à la plateforme Java).
Ce bytecode a ensuite vocation à être interprété sur unemachine virtuelle Java (JVM en anglais), un programme écrit spécifiquement pour la machine cible qui interprète lebytecode Java et fait exécuter par la machine lesinstructions traduites en code natif.
Noter que même s’il y a explicitement une première phase de compilation, le bytecode Java est soit interprété, soit converti à la volée en code natif par uncompilateur à la volée (just in time, JIT).
Les premières implémentations du langage utilisaient une machine virtuelle interprétée pour obtenir la portabilité. Ces implémentations produisaient des programmes qui s’exécutaient plus lentement que ceux écrits en langage compilé (C, C++, etc.) si bien que le langage souffrit d’une réputation de faibles performances.
Des implémentations plus récentes de la machine virtuelle Java (JVM) produisent des programmes beaucoup plus rapides qu’auparavant, en utilisant différentes techniques :
La première technique est de compiler directement en code natif comme un compilateur traditionnel, supprimant complètement la phase de bytecode. Des compilateurs Java tels queGNU Compiler for Java (GCJ) compilent ainsi directement le Java encode objet natif pour la machine cible. On obtient ainsi de bonnes performances, mais aux dépens de la portabilité : le code final produit par ces compilateurs ne peut de ce fait être exécuté que sur une seule architecture ;
Une autre technique appeléecompilation « juste-à-temps », ou « à la volée » (just in time, JIT), traduit le byte code en code natif durant la phase de lancement du programme ;
Certaines machines virtuelles plus sophistiquées utilisent unerecompilation dynamique durant laquelle la machine virtuelle analyse le comportement du programme et en recompile sélectivement certaines parties. La recompilation dynamique permet d’obtenir de meilleurs résultats que la compilation statique car les compilateurs dynamiques peuvent optimiser en fonction de leur connaissance de l’environnement cible et des classes qui sont utilisées.
La compilation JIT et la recompilation dynamique permettent à Java de tirer profit de la rapidité du code natif sans perdre la portabilité.
Après que Sun eut constaté que l’implémentation de Microsoft ne supportait pas les interfaces RMI etJNI, et comportait des éléments spécifiques à certaines plateformes par rapport à sa plateforme initiale, Sun déposa plainte en justice contre Microsoft[83], et obtint des dommages et intérêts (20 millions de dollars). Cet acte de justice renforça encore les termes de la licence de Sun. En réponse, Microsoft arrêta le support de Java sur ses plateformes et, sur les versions récentes de Windows,Internet Explorer ne supporte pas les applets Java sans ajouter de plug-in. Cependant, Sun met à disposition gratuitement des environnements d’exécution de Java pour les différentes plateformes Microsoft.
La portabilité est techniquement un objectif difficile à atteindre et le succès de Java en ce domaine est mitigé. Quoiqu’il soit effectivement possible d’écrire des programmes pour la plateforme Java qui fonctionnent correctement sur beaucoup de machines cibles, le nombre important de plateformes avec de petites erreurs et des incohérences a abouti à un détournement du slogan de Sun « Write once, run anywhere » (« Écrire une fois, exécuter n'importe où ») en« Write once, debug everywhere » (« Écrire une fois, déboguer partout ») !
L’indépendance de Java vis-à-vis de la plateforme est cependant un succès avec les applications côté serveur comme lesservices web, les servlets et lesJavaBeans aussi bien que les systèmes embarqués surOSGi, utilisant l’environnementEmbedded Java.
La plateforme Java fut l’un des premiers systèmes à offrir le support de l’exécution du code à partir de sources distantes. Uneapplet peut fonctionner dans lenavigateur web d’un utilisateur, exécutant du code téléchargé d’un serveurHTTP. Le code d’une applet fonctionne dans un espace très restrictif, ce qui protège l’utilisateur des codes erronés ou mal intentionnés. Cet espace est délimité par un objet appelégestionnaire de sécurité. Un tel objet existe aussi pour du code local, mais il est alors par défaut inactif.
Le gestionnaire de sécurité (la classeSecurityManager) permet de définir un certain nombre d’autorisations d’utilisation des ressources du système local (système de fichiers, réseau, propriétés système…). Une autorisation définit :
Un code accesseur (typiquement, une applet — éventuellement signée — envoyée depuis unserveur web) ;
Une ressource locale concernée (par exemple un répertoire) ;
Un ensemble de droits (par exemple lire/écrire).
Les éditeurs d’applet peuvent demander uncertificat pour leur permettre designer numériquement une applet comme sûre, leur donnant ainsi potentiellement (moyennant l’autorisation adéquate) la permission de sortir de l’espace restrictif et d’accéder aux ressources du système local.
Le fichier source porte presque toujours le nom de la classe avec l'extension « .java » (ici « HelloWorld.java », ce serait même obligatoire car la classe possède l'attributpublic dans sa déclaration — la rendant alors accessible à tout autre programme). On peut compiler puis exécuter cet exemple sur le terminal avec les commandes suivantes (sousLinux) :
La ligne « export CLASSPATH=. » sert à indiquer à Java qu’il doit également chercherles programmes class dans le répertoire courant.Ce chemin peut également être spécifié au lancement du programme par l’option-classpath (ou-cp en abrégé) :
(*) ces mots clefs sont réservés mais n'ont pas de signification pour le compilateur (il est juste interdit d'employer ce nom pour une variable par exemple) ;
(1.2), (1.4) et (5.0) ces mots clefs ont été ajoutés avec la version indiquée du langage.
Uneclasse est la description de données appelées attributs, et d’opérations appelées méthodes. Il s'agit d'un modèle de définition pour des objets ayant le même ensemble d’attributs, et le même ensemble d’opérations. À partir d’une classe on peut créer un ou plusieurs objets par instanciation ; chaque objet est uneinstance d’une seule classe.
Visibilité :
Public : le motclass est alors précédé depublic, tout utilisateur qui importe le paquetage peut utiliser la classe. Dans ce cas elle doit être définie dans un fichier qui a pour nom le nom de la classe.
Privé : le motclass est alors précédé deprivate, seules des classes définies dans le même fichier peuvent utiliser cette classe.
Paquetage : le motclass n’est pas précédé de mot particulier, toutes les classes du paquetage peuvent utiliser la classe.
Ensemble des valeursUnicode (valeurs de U+0000 à U+FFFF, 4 chiffres obligatoires après'\u') Les 128 premiers caractères sont les codes ASCII et se notent entre apostrophes :'a','1','\'','\n'.
Le tableau ci-dessus recense les types de base, cependant il existe en Java d'autres types qui sont des objets et sont à utiliser en tant que tel. Par exemple pour définir un entier on peut utiliser le type 'Integer' dont la valeur d'initialisation par défaut vaudranull
Pour instancier une variable, la syntaxe (ici la même qu'en C) est la suivante :
Il est souvent nécessaire de stocker de nombreuses données dans des collections : liste d’achats, notes des élèves, etc.Les collections peuvent être consultées, modifiées, on peut les trier, les recopier, les supprimer, etc. Elles peuvent avoir une taille fixe ou variable.
Les collections à taille fixe sont moins lourdes que les collections à taille variable.
Comme en C, les indices d'un tableau de taillen vont de 0 à n-1. Un des plus grands avantages des tableaux est l’accès en temps constant O(1), à chaque case du tableau.
Les tableaux sont des objets en Java. Pour initialiser un tableautab d’entiers de 10 cases, on peut écrire (entre autres) :
int[]tab=newint[10];
ou :
inttab[]=newint[10];
ou :
inttab[]={0,0,0,0,0,0,0,0,0,0};
Les indices detab vont de 0 à 9, et il ne pourra pas être redimensionné.
Chaque élément detab est initialisé à sa valeur par défaut, ici 0 car il s'agit d'un tableau d'entiers (int). La valeur par défaut d'un objet estnull, celle d'un booléen estfalse.
Pour lire ou modifier l'élément detab d'indicei, pour 0 ≤ i ≤ 9, on utilisetab[i].
Exemple : Pour attribuer la valeur 2 à une case detab, on écrit :tab[i] = 2;
La propriétélength (exemple :tab.length) fournit le nombre d'éléments du tableau. Si on essaie de modifier un élément qui n’existe pas, par exemple avectab [10] = 4;, une exceptionIndexOutOfBoundsException est déclenchée (notre tableautab ne contient que 10 cases, numérotées de 0 à 9 inclus).
La classe abstraiteAbstractList est fournie pour implémenter les collections à taille variable.
Pour initialiser une ArrayList il faut importer la classejava.util.ArrayList et écrireliste = new ArrayList<T>(); ouliste = new ArrayList<>(); depuis le JDK 7.0.
Depuis le JDK 1.5, on a la possibilité d’indiquer le type des éléments contenus dans une ArrayList : Entiers,chaînes de caractères ou autres objets.
Cette collection est vide après l’appel du constructeur ;
On peut ajouter autant d’éléments que l’on veut.
Pour ajouter un élément on écritliste.add(Objet);
Pour accéder à un élément de l’ArrayList :liste.get(index);
Pour connaître le nombre d’éléments que contient une liste :liste.size();
Pour supprimer un élément :liste.remove(index); les éléments qui suivent l’élément supprimé seront décalés à gauche.
Bien qu’elles aient toutes un rôle similaire, chaque boucle est pourtant adaptée à une situation :
Structuretant que (adaptée pour effectuer des opérations tant qu’une condition est remplie) :
while(<expressionbooléenne>){instruction(s)}
Structurefaire … tant que (comme la structuretant que mais la premièreitération est exécutée quelle que soit la condition, pour les autres itérations la condition doit être remplie) :
do{instruction(s)}while(<expressionbooléenne>);
Structurepour (adaptée lorsqu'une collection doit être parcourue en totalité pour traitement) :
Remarque : il est possible de combiner des conditions (expressions booléennes) en utilisant des opérateurs supplémentaires : le « ET » logique&& (instruction exécutée si toutes les conditions sont vraies) :
Enfin, il y a le « NON » logique! qui permet d'inverser le résultat d'une condition.
Il est possible de combiner ces opérations pour obtenir des structures conditionnelles complexes. On peut ajouter des parenthèses pour définir les priorités des conditions (comme dans un calcul). Dans les autres cas, la JVM effectue les différentes vérifications de gauche à droite.
Structuresi … sinon : condition avec alternative unique
Le choix d'exécution des instructions est déterminé par l'expression suivantswitch dont le type peut être entier (int,char,byte oushort ou classes enveloppes correspondantes), énuméré (enum) ouString (chaîne de caractères, depuis Java 7 seulement).
Remarque :L'opérateur conditionnel ouopérateur ternaire? : peut permettre d'éviter l'utilisation d'une instruction conditionnelle. Une expression conditionnelle aura l'une ou l'autre valeur après test de la condition booléenne :
L'instructionbreak fait sortir immédiatement de la boucle en cours (for,while,do), mais permet également de sortir d’une clause contenue dans unswitch. Si lebreak est omis, l'exécution duswitch se poursuit decase encase.
L'instructioncontinue termine l’itération en cours et continue à la prochaine. Son usage ainsi que celui debreak dans les boucles est controversé (de la même manière quegoto dans d'autres langages structurés). Elle tendrait à favoriser un type de programmation non structurée (programmation spaghetti).
L’instructionreturn termine une méthode. Avecreturn uneValeur, uneValeur sera renvoyée à la méthode appelante.
Le bloc de codefinally sera exécuté quel que soit le résultat lorsque le programme sortira du bloctry-catch.
Voici un exemple de capture d’une exception :
FileOutputStreamfos=null;try{//Chacune de ces deux instructions peut générer une exception// création d'un flux pour écrire dans un fichierfos=newFileOutputStream(...);// écriture de données dans ce fluxfos.write(...);}catch(IOExceptione){//Gestion de l'erreur de création ou d'écriture dans le fluxe.printStackTrace();}finally{//Cette section de code est toujours exécutée, qu’il y ait une exception ou pas// fermeture du flux s'il a été ouvertif(fos!=null)fos.close();}
Cet exemple permet d’illustrer le mécanisme des exceptions en Java. Dans le cas d’une erreur d’entrée/sortie dans le bloctry, l’exécution reprend dans le bloccatch correspondant à cette situation (exception de typeIOException).
Dans ce bloccatch, la variablee référence l’exception qui s’est produite. Ici, nous invoquons la méthodeprintStackTrace() qui affiche dans la console des informations sur l’exception qui s’est produite : nom, motif, état de la pile d’appels au moment de la levée de l’exception et, éventuellement, numéro de ligne auquel l’erreur s’est produite.
Le blocfinally est ensuite exécuté (ici pour refermer les ressources utilisées). Il ne s’agit ici que d’un exemple, l’action à mettre en œuvre lorsqu’une exception survient dépend du fonctionnement général de l’application et de la nature de l’exception.
Un type générique est autrement appelé un Template, il prend un ou plusieurs autres types en arguments.Le type passé en paramètre est déterminé lors de l'instanciation.
Cela permet notamment dans le cadre des ArrayList d'éviter les transtypages.
Ces types génériques ne sont utilisés qu'à la compilation, et non directement dans le bytecode.
Différence avec le C++ : les templates en C++ dupliquent une classe pour chaque type. Java, au contraire, agit au moment de la compilation comme si on avait dupliqué les classes de ces types intrinsèques mais ne traite en réalité qu'avec une seule classe.
Les spécifications du langage Java précisent qu’il est formé de caractères au formatUTF-16, ce qui permet l’utilisation dans le code source de tous les caractères existant dans le monde :
La plate-forme de développement Java propose un gestionnaire de sécurité[84] (cf. supra § Exécution sécurisée de code distant) qui permet à un utilisateur de tester un exécutable douteux dans un « bac à sable » pour éviter de contaminer ses périphériques de stockage. Ce mode d'exécution restreint l'accès par l'exécutable à des options et interfaces exploitées par leslogiciels malveillants : les manipulations sur les bases de fichiers locaux, plusieurs commandes systèmes ou de bas niveau, ou l'accès auréseau informatique.
Peu après 2010, des chercheurs ont mis au jour plusieurs failles de sécurité dans les versions de Java les plus courantes : celle d'Oracle, par exemple, laisse filtrer du code non-autorisé malgré le mécanisme d’isolation, et expose ses utilisateurs à des piratages. Ces failles n'affectent que les applications Java exécutant aléatoirement des programmes non explicitement approuvés par l'utilisateur : greffons de navigateur web exploitant des applets Java téléchargés depuis des sites ouverts.
Le 31 août 2012, une grave faille de sécurité a été détectée dans Java 6 et 7 pourMicrosoft Windows,OS X et Linux, qui permettait deprendre le contrôle à distance en chargeant unepage web factice[85],[86]. La même faille a été retrouvée dansJava 5 par la suite[87]. Ainsi, le 10 janvier 2013, trois spécialistes de l'informatique prirent position contre Java, affirmant à l'AgenceReuters que ce langage n'était pas sûr et que les internautes feraient bien de le désactiver par défaut. Jaime Blasco, directeurs du laboratoire d'AlienVault Labs, a déclaré :« Java est un vrai fouillis. Ce n'est pas sûr. Il faut le désactiver[88]. »
En 2014, compte tenu de ces problèmes de sécurité et de vulnérabilité avec Java, l'influenceurBrian Krebs appelait les internautes à retirer le greffon Java de leur navigateur[89].« C'était prometteur au début, mais son utilité pour la navigation sur le web a fait long feu, et c'est à présent un cauchemar qui fait les délices des cyber-criminels aux dépens des internautes[90]. »
Dans le cas particulier du greffon Java denavigateurs web, comme il n'est indispensable que pour un petit nombre d'applications en ligne, plusieurs experts ensécurité informatique recommandent de limiter au maximum le recours à celui-ci[91],[92].
Avec la disparition progressive du greffon Java de navigateur durant les années 2010, et l'évolution par des mises à jour, Java n'est plus considéré à la fin des années 2010 comme un risque majeur pour les ordinateurs de bureau[93]. Il a, au début des années 2020, en tant que premier langage des applications d'entreprise, un niveau de sécurité similaire à son principal concurrent dans ce domaine,Microsoft .NET[94].
Dans son essai sur la conception des logiciels[95],J. Ousterhout, l'auteur deTcl/Tk, diagnostique chez les concepteurs de Java une forme d'idée fixe qu'il appelle « classite » (classitis), à savoir que« comme lesclasses objet sont favorables à la structuration du code, plus on crée de classes, mieux c'est. » Selon cet auteur, la multiplication du nombre de classes objet, si elle favorise l'écriture de routines individuellement courtes et faciles à analyser, augmente corrélativement la complexité de l'ensemble d'un programme et le rend difficile à comprendre, à corriger et à étendre.
Lorsque Java 5.0 a été doté de laprogrammation générique, son répertoire de classes objet (dont plusieurs étaient même déjàdésuètes!) était très fourni. Il a été décidé d'utiliser la généricité des procédures en mode « ignorer » (Type erasure) pour favoriser unecompatibilité ascendante et réutiliser le code des classes existantes ; mais cette décision a limité les avantages de la programmation générique par rapport à d'autres langages[96],[97], et l'accumulation demétacaractères dans le typage a rendu Java incohérent[98].
Java n'a pas, en propre, de type d'entier non signé : dans ce langage, ils sont donc souvent produits par des sous-programmes écrits enlangage C. Cette lacune s'oppose, du reste, à un passage de paramètre fluide entre les deux langages, C et Java. Enfin, on sait que les grands entiers positifs sont très utilisés, notamment pour lacryptographie, ce qui rend Java moins attractif pour ce genre de traitement[99].Bien qu'on puisse en partie contourner ce problème par conversion de code et recours à des types de données plus grands (par exemple en utilisant un entier 64 bits pour coder un entier 32 bits non signé), Java est malcommode pour la manipulation des grands entiers[100].
S'il est vrai que l'arithmétique en virgule flottante de Java respecte pour l'essentiel les directives de la normeIEEE 754 (Standard for Binary Floating-Point Arithmetic), elle s'en écarte sur quelques points (par exemple l'indicateur binaire de débordement de type ou la gestion des arrondis), même lorsque l'on active le modificateurstrictfp. En outre, les types de flottants de précision étendue reconnus par la norme 754 et déjà disponibles sur de nombreux processeurs, n'existent pas en Java[101],[102].
Dans les débuts de Java (c'est-à-dire avant le lancement de lamachine virtuelle HotSpot dans Java 1.3 en 2000), la lenteur de Java était bien connue. La plate-forme comparativeBenchmarks avait notamment relevé que Java était deux fois plus lent que le langage C[103],[104],[105].
Mais il est vrai que la vitesse d'exécution de Java s'est considérablement améliorée depuis[106]. Lacompilation à la volée, moyennant une certaine discipline dans l'écriture du code source, est aujourd'hui à peine inférieure à celle des compilateurs natifs[106],[107].
Les JavaStyle sont des conventions de programmation en langage Java définies par Sun. Le respect de conventions strictes assure une homogénéité dans lecode source d’une application développée par toute une équipe et favorise la diffusion du code source auprès d’une communauté partageant les mêmes conventions de codage.
Lelowercamel case est utilisé pour les noms de méthodes et de variables.
Sun fournit un grand nombre deframeworks et d’API afin de permettre l’utilisation de Java pour des usages très diversifiés.
On distingue essentiellement quatre grandsframeworks :
Java SE (anciennement J2SE) : Ceframework est destiné aux applications pour poste de travail ;
Java EE (anciennement J2EE) : Ceframework est spécialisé dans les applications serveurs. Il contient pour ce faire un grand nombre d’API et d’extensions ;
Java ME (anciennement J2ME) : Ceframework est spécialisé dans les systèmes embarqués et décline plusieurs variantes pour les applications mobiles, téléphones, télévisions, ainsi que les cartes à puces notammentJava Card.
La programmation peut se faire depuis uneinvite de commande en lançant un compilateur Java (souvent nomméjavac), mais pour avoir plus de confort, il est préférable d’utiliser unenvironnement de développement intégré ou IDE (qui permet de compiler automatiquement), certains sont gratuits.Par exemple :
Un programme Java peut être produit avec des outils qui automatisent le processus de construction (c'est-à-dire l'automatisation de certaines tâches faisant appel à un nombre potentiellement grand de dépendances comme l'utilisation de bibliothèques, la compilation, la génération d'archives, de documentation, le déploiement, etc.).Les plus utilisés sont :
Apache Ant (génération portable, décrite en XML) ;
Apache Maven (génération portable, décrite en XML) ;
Gradle (génération portable, en utilisant le langageGroovy) ;
SCons (génération portable, en utilisant le langagePython). Exemple :
↑MickaelBaron, « Java 9 est disponible, la plateforme se met aux modules : tour d'horizon des nouveautés »,Developpez.com,(lire en ligne, consulté le)