Apprenez Java de A à Z

Alors, vous souhaitez programmer en Java? C'est génial, et vous êtes au bon endroit. La série Java 101 fournit une introduction autoguidée à la programmation Java, en commençant par les bases et en couvrant tous les concepts de base que vous devez connaître pour devenir un développeur Java productif. Cette série est technique, avec de nombreux exemples de code pour vous aider à comprendre les concepts au fur et à mesure. Je suppose que vous avez déjà une certaine expérience en programmation, mais pas en Java.

Ce premier article présente la plate-forme Java et explique la différence entre ses trois éditions: Java SE, Java EE et Java ME. Vous découvrirez également le rôle de la machine virtuelle Java (JVM) dans le déploiement d'applications Java. Je vous aiderai à mettre en place un kit de développement Java (JDK) sur votre système afin que vous puissiez développer et exécuter des programmes Java, et je vous présenterai l'architecture d'une application Java typique. Enfin, vous apprendrez à compiler et à exécuter une application Java simple.

Mise à jour pour Java 12 et le nouveau JShell

Cette série a été mise à jour pour Java 12 et comprend une introduction rapide au nouveau jshell: un outil interactif pour apprendre Java et prototyper du code Java.

télécharger Obtenir le code Téléchargez le code source des exemples d'applications dans ce didacticiel. Créé par Jeff Friesen pour JavaWorld.

Qu'est-ce que 'java?

Vous pouvez considérer Java comme un langage orienté objet à usage général qui ressemble beaucoup au C et au C ++, mais qui est plus facile à utiliser et vous permet de créer des programmes plus robustes. Malheureusement, cette définition ne vous donne pas beaucoup d'informations sur Java. En 2000, Sun Microsystems (créateur de la plateforme Java) décrivait Java de cette manière: 

Java est un langage informatique dynamique simple, orienté objet, intelligent réseau, interprété, robuste, sécurisé, indépendant de l'architecture, portable, hautes performances, multithread.

Considérons chacune de ces définitions séparément.

Java est un langage simple . Java a été initialement modélisé après C et C ++, sans certaines fonctionnalités potentiellement déroutantes. Les pointeurs, l'héritage d'implémentations multiples et la surcharge d'opérateurs sont des fonctionnalités C / C ++ qui ne font pas partie de Java. Une fonctionnalité non obligatoire en C / C ++, mais essentielle à Java, est une fonction de récupération de place qui récupère automatiquement les objets et les tableaux.

Java est un langage orienté objet . La focalisation orientée objet de Java permet aux développeurs de travailler sur l'adaptation de Java pour résoudre un problème, plutôt que de nous forcer à manipuler le problème pour répondre aux contraintes du langage. Ceci est différent d'un langage structuré comme C. À titre d'exemple, alors que Java vous permet de vous concentrer sur les objets de compte d'épargne, C vous oblige à réfléchir séparément à l' état du compte d'épargne (un tel solde) et aux comportements (tels que le dépôt et le retrait).

Java est un langage familier avec les réseaux . La vaste bibliothèque réseau de Java facilite la prise en charge des protocoles réseau TCP / IP (Transmission Control Protocol / Internet Protocol) tels que HTTP (HyperText Transfer Protocol) et FTP (File Transfer Protocol), et simplifie la tâche de connexion au réseau. De plus, les programmes Java peuvent accéder aux objets sur un réseau TCP / IP, via des URL (Uniform Resource Locators), avec la même facilité que vous auriez pour y accéder à partir du système de fichiers local.

Java est un langage interprété . Lors de l'exécution, un programme Java s'exécute indirectement sur la plate-forme sous-jacente (comme Windows ou Linux) via une machine virtuelle (qui est une représentation logicielle d'une plate-forme hypothétique) et l'environnement d'exécution associé. La machine virtuelle traduit les bytecodes du programme Java (instructions et données associées) en instructions spécifiques à la plate-forme par interprétation. L'interprétation consiste à déterminer ce que signifie une instruction de bytecode, puis à choisir des instructions équivalentes spécifiques à une plate-forme «en conserve» à exécuter. La machine virtuelle exécute ensuite ces instructions spécifiques à la plate-forme.

L'interprétation facilite le débogage des programmes Java défectueux car davantage d'informations de compilation sont disponibles au moment de l'exécution. L'interprétation permet également de retarder l'étape de liaison entre les éléments d'un programme Java jusqu'à l'exécution, ce qui accélère le développement.

Java est un langage robuste . Les programmes Java doivent être fiables car ils sont utilisés à la fois dans des applications grand public et critiques, allant des lecteurs Blu-ray aux systèmes de navigation de véhicule ou de contrôle aérien. Les fonctionnalités de langage qui aident à rendre Java robuste incluent les déclarations, la vérification des types en double au moment de la compilation et à l'exécution (pour éviter les problèmes de non-concordance de version), de vrais tableaux avec vérification automatique des limites et l'omission de pointeurs. (Voir «Fonctionnalités du langage Java élémentaire» pour commencer avec les types de langage Java, les littéraux, les variables, etc.)

Un autre aspect de la robustesse de Java est que les boucles doivent être contrôlées par des expressions booléennes au lieu d'expressions entières où 0 est faux et une valeur différente de zéro est vraie. Par exemple, Java n'autorise pas une boucle de style C, par exemple while (x) x++;parce que la boucle peut ne pas se terminer à l'endroit prévu. Au lieu de cela, vous devez fournir explicitement une expression booléenne, telle que while (x != 10) x++;(ce qui signifie que la boucle s'exécutera jusqu'à ce qu'elle xsoit égale à 10).

Java est un langage sécurisé . Les programmes Java sont utilisés dans des environnements en réseau / distribués. Étant donné que les programmes Java peuvent migrer et s'exécuter sur les différentes plates-formes d'un réseau, il est important de protéger ces plates-formes contre les codes malveillants qui pourraient propager des virus, voler des informations de carte de crédit ou effectuer d'autres actes malveillants. Les fonctionnalités du langage Java qui prennent en charge la robustesse (comme l'omission de pointeurs) fonctionnent avec des fonctionnalités de sécurité telles que le modèle de sécurité Java sandbox et le chiffrement à clé publique. Ensemble, ces fonctionnalités empêchent les virus et autres codes dangereux de faire des ravages sur une plate-forme sans méfiance.

En théorie, Java est sécurisé. Dans la pratique, diverses vulnérabilités de sécurité ont été détectées et exploitées. En conséquence, Sun Microsystems d'alors et Oracle continuent désormais de publier des mises à jour de sécurité.

Java est un langage indépendant de l'architecture . Les réseaux connectent des plates-formes avec différentes architectures basées sur divers microprocesseurs et systèmes d'exploitation. Vous ne pouvez pas vous attendre à ce que Java génère des instructions spécifiques à la plate-forme et que ces instructions soient «comprises» par tous les types de plates-formes qui font partie d'un réseau. Au lieu de cela, Java génère des instructions bytecode indépendantes de la plate-forme qui sont faciles à interpréter pour chaque plate-forme (via sa mise en œuvre de la JVM).

Java est un langage portable . La neutralité de l'architecture contribue à la portabilité. Cependant, la portabilité de Java ne se résume pas à des instructions de bytecode indépendantes de la plate-forme. Considérez que les tailles de type entier ne doivent pas varier. Par exemple, le type entier 32 bits doit toujours être signé et occuper 32 bits, quel que soit l'endroit où l'entier 32 bits est traité (par exemple, une plate-forme avec des registres 16 bits, une plate-forme avec des registres 32 bits ou une plate-forme avec registres 64 bits). Les bibliothèques Java contribuent également à la portabilité. Le cas échéant, ils fournissent des types qui connectent le code Java avec des capacités spécifiques à la plate-forme de la manière la plus portable possible.

Java est un langage performant . L'interprétation donne un niveau de performance généralement plus que suffisant. Pour les scénarios d'application à très hautes performances, Java utilise la compilation juste à temps, qui analyse les séquences d'instructions de bytecode interprétées et compile les séquences d'instructions fréquemment interprétées en instructions spécifiques à la plate-forme. Les tentatives ultérieures d'interpréter ces séquences d'instructions de bytecode aboutissent à l'exécution d'instructions équivalentes spécifiques à la plate-forme, ce qui entraîne une amélioration des performances.

Java est un langage multithread . Pour améliorer les performances des programmes devant accomplir plusieurs tâches à la fois, Java prend en charge le concept d' exécution threadée . Par exemple, un programme qui gère une interface utilisateur graphique (GUI) en attendant l'entrée d'une connexion réseau utilise un autre thread pour effectuer l'attente au lieu d'utiliser le thread GUI par défaut pour les deux tâches. Cela maintient l'interface graphique réactive. Les primitives de synchronisation de Java permettent aux threads de communiquer en toute sécurité des données entre eux sans corrompre les données. (Voir la programmation threadée en Java abordée ailleurs dans la série Java 101.)

Java est un langage dynamique . Étant donné que les interconnexions entre le code du programme et les bibliothèques se produisent de manière dynamique lors de l'exécution, il n'est pas nécessaire de les lier explicitement. En conséquence, lorsqu'un programme ou l'une de ses bibliothèques évolue (par exemple, pour une correction de bogue ou une amélioration des performances), un développeur n'a qu'à distribuer le programme ou la bibliothèque mis à jour. Bien que le comportement dynamique entraîne moins de code à distribuer lors d'un changement de version, cette stratégie de distribution peut également entraîner des conflits de version. Par exemple, un développeur supprime un type de classe d'une bibliothèque ou le renomme. Lorsqu'une entreprise distribue la bibliothèque mise à jour, les programmes existants qui dépendent du type de classe échouent. Pour réduire considérablement ce problème, Java prend en charge un type d'interface, qui est comme un contrat entre deux parties. (Voir interfaces, types et autres fonctionnalités du langage orienté objet discutées ailleurs dans la série Java 101.)

Déballer cette définition nous en apprend beaucoup sur Java. Plus important encore, il révèle que Java est à la fois un langage et une plate-forme. Vous en apprendrez plus sur les composants de la plate-forme Java, à savoir la machine virtuelle Java et l'environnement d'exécution Java, plus loin dans ce didacticiel.

Trois éditions de Java: Java SE, Java EE et Java ME

Sun Microsystems a lancé le kit de développement logiciel (JDK) Java 1.0 en mai 1995. Le premier JDK a été utilisé pour développer des applications de bureau et des applets, et Java a ensuite évolué pour englober la programmation de serveurs d'entreprise et d'appareils mobiles. Stocker toutes les bibliothèques nécessaires dans un seul JDK aurait rendu le JDK trop volumineux pour être distribué, en particulier parce que la distribution dans les années 1990 était limitée par des CD de petite taille et des vitesses de réseau lentes. Comme la plupart des développeurs n'avaient pas besoin de la dernière API (un développeur d'applications de bureau n'aurait guère besoin d'accéder aux API Java d'entreprise), Sun a factorisé Java en trois éditions principales. Ceux-ci sont finalement devenus connus sous le nom de Java SE, Java EE et Java ME:

  • Java Platform, Standard Edition (Java SE) est la plate-forme Java permettant de développer des applications côté client (qui s'exécutent sur des postes de travail) et des applets (qui s'exécutent dans des navigateurs Web). Notez que pour des raisons de sécurité, les applets ne sont plus officiellement pris en charge.
  • Java Platform, Enterprise Edition (Java EE ) est la plate-forme Java basée sur Java SE, qui est utilisée exclusivement pour développer des applications serveur orientées entreprise. Les applications côté serveur incluent les servlets Java , qui sont des programmes Java similaires aux applets mais exécutés sur un serveur plutôt que sur un client. Les servlets sont conformes à l'API Java Servlet.
  • Java Platform, Micro Edition (Java ME) est également basé sur Java SE. Il s'agit de la plate-forme Java pour le développement des MIDlets , qui sont des programmes Java qui s'exécutent sur des périphériques d'information mobiles, et des Xlets , qui sont des programmes Java qui s'exécutent sur des périphériques intégrés.

Java SE est la plate-forme de base pour Java et est au centre de la série Java 101. Les exemples de code seront basés sur la version la plus récente de Java au moment de la rédaction, Java 12.

La plateforme Java et JVM

Java est à la fois un langage de programmation et une plate-forme pour exécuter du code Java compilé. Cette plate-forme se compose principalement de la JVM, mais comprend également un environnement d'exécution qui prend en charge l'exécution de la JVM sur la plate-forme sous-jacente (native). La JVM comprend plusieurs composants pour charger, vérifier et exécuter du code Java. La figure 1 montre comment un programme Java s'exécute sur cette plate-forme. 

Jeff Friesen

En haut du diagramme se trouve une série de fichiers de classe de programme, dont l'un est désigné comme fichier de classe principal. Un programme Java comprend au moins le fichier de classe principal, qui est le premier fichier de classe à charger, vérifier et exécuter.

La JVM délègue le chargement de classe à son composant de chargeur de classe. Les chargeurs de classe chargent des fichiers de classe à partir de diverses sources, telles que des systèmes de fichiers, des réseaux et des fichiers d'archive. Ils isolent la JVM des subtilités du chargement de classe.

Un fichier de classe chargé est stocké en mémoire et représenté comme un objet créé à partir de la Classclasse. Une fois chargés, le vérificateur de bytecode vérifie les différentes instructions de bytecode pour s'assurer qu'elles sont valides et ne compromettent pas la sécurité.

Si les codes d'octets du fichier de classe ne sont pas valides, la machine virtuelle Java s'arrête. Sinon, son composant interpréteur interprète le bytecode une instruction à la fois. L'interprétation identifie les instructions de bytecode et exécute des instructions natives équivalentes.

Certaines séquences d'instructions de bytecode s'exécutent plus fréquemment que d'autres. Lorsque l'interpréteur détecte cette situation, le compilateur juste-à-temps (JIT) de la JVM compile la séquence de bytecode en code natif pour une exécution plus rapide.

Pendant l'exécution, l'interpréteur rencontre généralement une requête pour exécuter le bytecode d'un autre fichier de classe (appartenant au programme ou à une bibliothèque). Lorsque cela se produit, le chargeur de classe charge le fichier de classe et le vérificateur de bytecode vérifie le bytecode du fichier de classe chargé avant son exécution. Pendant l'exécution également, les instructions de bytecode peuvent demander à la JVM d'ouvrir un fichier, d'afficher quelque chose à l'écran, d'émettre un son ou d'effectuer une autre tâche nécessitant une coopération avec la plate-forme native. La machine virtuelle Java répond en utilisant sa technologie de pont JNI (Java Native Interface) pour interagir avec la plate-forme native pour effectuer la tâche.