Né chez Sun Microsystems pour des appareils électroniques grand public, lancé en 1995 avec l'essor du Web, Java est devenu l'un des langages les plus utilisés au monde : serveurs des banques et des administrations, applications Android, cartes à puce, traitement de données massives, et même le jeu Minecraft. Cinq planches pour découvrir son bytecode et sa machine virtuelle, ses objets, ses collections, ses lambdas, puis pour exécuter de vrais programmes Java.
En 1991, chez Sun Microsystems, une petite équipe menée par James Gosling travaille sur le projet « Green » : programmer les futurs appareils électroniques grand public, comme les décodeurs de télévision. Ces appareils utilisent des processeurs très différents ; il faut donc un langage dont les programmes fonctionnent partout, sans être recompilés. Gosling conçoit Oak, qui reprend la syntaxe du C++ en le simplifiant : pas de pointeurs manipulables, une gestion automatique de la mémoire, des objets partout. Le marché de la télévision interactive ne décolle pas, mais le Web, lui, explose : rebaptisé Java (un nom de café), le langage est présenté le 23 mai 1995, avec la promesse « Write once, run anywhere » : écrit une fois, exécuté partout.
Le compilateur javac ne produit pas de code pour un processeur réel, mais du bytecode : les instructions d'une machine imaginaire à pile, la machine virtuelle Java (JVM). Chaque système (Windows, macOS, Linux, Android, carte à puce…) possède sa propre JVM, qui exécute le même fichier .class. Voici le vrai bytecode produit par javac pour quatre méthodes, extrait avec l'outil javap, et sa simulation pas à pas.
iload empile une variable, istore la range, irem remplace les deux valeurs du sommet par le reste de leur division, if_icmpgt compare et saute, invokestatic appelle une méthode.factorielle(13) déborde : un int Java a toujours 32 bits.En Java, presque tout est objet. Une classe décrit des objets : leurs données (les champs) et leurs actions (les méthodes). Une classe peut en étendre une autre et redéfinir ses méthodes : un Carre est un Rectangle, qui est une Forme. Quand le programme demande f.aire() à une forme, c'est la JVM qui choisit, au moment de l'exécution, la méthode de la classe réelle de l'objet : c'est le polymorphisme. Suivez la boucle du programme Formes.
Forme[] formes, rangés dans le tas (la mémoire des objets). Pour l'objet en cours, la flèche montre la classe dont la méthode aire() est réellement exécutée.Forme est abstraite : elle annonce les méthodes aire() et perimetre() sans les écrire, et on ne peut pas créer de « forme » tout court. Le Carre n'écrit aucune méthode : il hérite de celles du Rectangle. Le code qui parcourt le tableau ne connaît que Forme ; on peut ajouter une nouvelle sorte de forme sans le modifier. Java n'autorise qu'une seule classe parente (extends), mais une classe peut réaliser plusieurs interfaces (implements), des contrats qui listent des méthodes à fournir. Toutes les classes héritent de Object, d'où la méthode toString() que l'on redéfinit ici.Depuis Java 1.2, la bibliothèque standard offre des collections prêtes à l'emploi : listes (ArrayList), ensembles, tables d'association. La plus utilisée, HashMap, retrouve une valeur à partir d'une clé en un temps presque constant, même parmi des millions. Le secret : un calcul de hachage. Pour un mot, hashCode() calcule un entier à partir de ses lettres (h = 31 × h + code de la lettre) ; ce nombre désigne une case d'un tableau. Regardez les mots d'une phrase se ranger dans les cases, et le tableau doubler quand il se remplit.
(h ^ (h >>> 16)) & (taille − 1) : on mélange les bits de poids fort et de poids faible, puis on garde les derniers bits. Quand le nombre d'éléments dépasse les trois quarts du tableau (le facteur de charge 0,75), le tableau double et les éléments sont redistribués. C'est pourquoi l'ordre dans lequel une HashMap énumère ses clés paraît aléatoire et peut changer au fil des ajouts : il ne faut jamais compter dessus. Pour un ordre alphabétique, on utilise une TreeMap (arbre équilibré) ; pour l'ordre d'insertion, une LinkedHashMap. Si une case accumule plus de 8 éléments, Java la transforme en arbre.Java 8 introduit les expressions lambda, de petites fonctions écrites sur place : m -> m.length() > 4, et les flux (Stream), qui enchaînent des opérations sur une collection : filtrer, transformer, trier, limiter. Un flux est paresseux : rien ne se passe avant l'opération finale, puis chaque élément traverse toute la chaîne avant le suivant, et le calcul s'arrête dès que le résultat est connu. Comparez les trois chaînes d'opérations sur dix mots.
filter s'arrête, sorted doit tout recevoir avant de laisser passer quoi que ce soit, limit et findFirst arrêtent le flux.map n'est appelé que pour trois mots, et les cinq derniers mots ne sont jamais lus : la paresse évite le travail inutile. Avec sorted, c'est différent : pour trier, il faut d'abord tous les mots, donc tous passent par filter. Ce style dit quoi calculer plutôt que comment le faire avec des boucles ; il se prête au calcul en parallèle (parallelStream()). Depuis, Java a ajouté le mot-clé var (2018), les record (2021), le filtrage par motifs dans switch et les threads virtuels (2023), qui permettent de lancer des millions de tâches simultanées.Voici un petit interpréteur Java, écrit pour cette page, qui exécute dans votre navigateur un sous-ensemble du langage : classes, constructeurs, héritage, classes abstraites, interfaces, polymorphisme, classes génériques ; types int, long, double, char, boolean avec les vrais débordements et les règles de conversion de Java ; tableaux à plusieurs dimensions ; String, StringBuilder, ArrayList, HashMap (avec son vrai ordre de parcours), Math, Arrays ; if, switch, boucles, exceptions avec try, catch, finally. L'affichage des réels et printf suivent exactement Java, réglé en français. Chaque exemple a aussi été compilé par javac et exécuté par la JVM d'OpenJDK 21.
public static void main(String[] args). Le type de chaque variable est déclaré, et le compilateur le vérifie. System.out.println écrit les réels avec un point, toujours ; printf et String.format suivent les conventions du pays de l'ordinateur, ici la France, d'où la virgule. Une exception non rattrapée arrête le programme avec un message sur la console d'erreur. Ce petit interpréteur ne connaît pas les lambdas, les flux, les threads ni la lecture au clavier ; essayez quand même de modifier les exemples, par exemple d'ajouter une forme dans l'exemple 2.Banques, assurances, commerce en ligne, administrations : une grande partie des applications de gestion tournent sur des serveurs Java, souvent avec le cadre Spring. Java est 4e du classement TIOBE d'octobre 2026.
Lancé en 2008, Android a choisi le langage Java pour ses applications, exécutées par sa propre machine virtuelle. Depuis 2019, Google privilégie Kotlin, un autre langage qui fonctionne sur la JVM et cohabite avec Java.
Java Card, une version minuscule de Java, fait fonctionner des milliards de cartes SIM, de cartes bancaires et de passeports électroniques : chaque carte contient une petite machine virtuelle.
Les grands outils de traitement de données, comme Hadoop, Kafka, Elasticsearch ou Spark (écrit en Scala, un autre langage de la JVM), reposent sur la machine virtuelle Java et sa capacité à exploiter des grappes de serveurs.
Minecraft, le jeu vidéo le plus vendu de l'histoire, a été écrit en Java en 2009 ; sa « Java Edition » est toujours la favorite des créateurs de modifications. Les environnements de développement IntelliJ IDEA et Eclipse sont eux-mêmes écrits en Java.
Java est enseigné dans de nombreuses universités et écoles d'ingénieurs pour la programmation orientée objet ; aux États-Unis, l'examen Advanced Placement d'informatique se passe en Java depuis 2004.
Les exemples de la planche 5, le bytecode de la planche 1, l'ordre de la HashMap de la planche 3 et l'ordre des appels des flux de la planche 4 ont été produits par javac et la JVM d'OpenJDK 21 au moment de la fabrication de la page, avec les réglages régionaux français. Votre navigateur refait tous ces calculs et les compare.