# Programmation Java/JDK

* Introduction
* La notion de machine virtuelle
* Installation
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Premier programme
** Commentaires
** Types de base
** Opérateurs
** Conditions
** Bloc de portée
** Itérations
** Tableaux
* Les classes en Java
** Membres
** Modificateurs d'accès
** Héritage
** Encapsulation
** Polymorphisme
** Classes abstraites
** Interfaces
** Classes internes
** Transtypage
** Types génériques
** Instanciation et cycle de vie
** « this »
** Objets comparables et clés
** Énumérations
** Exceptions
** Packages
* Classes de base
** Collections
** Nombre de taille arbitraire
** Tags Javadoc
** Annotations
** Entrées sorties
** Threads et synchronisation
** Méthodes natives
** Réflexion
** Regex
** JUnit
* Conclusion
* Exemples en Java
** Générer un carré magique
** Générer un triangle de Sierpiński
** XML
** Swing
*** Un premier exemple
*** Formulaire avec boutons sur image
*** Calcul de somme
*** Calcul de distance
* Annexes
** Les outils de base fournis avec le Java Development Kit
** Créer une archive Java
** Paramétrer la JVM
** Liste des mots réservés
** Débogage
** Java et les autres langages
* Introduction
* La notion de machine virtuelle
* Installation
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Premier programme
** Commentaires
** Types de base
** Opérateurs
** Conditions
** Bloc de portée
** Itérations
** Tableaux
* Les classes en Java
** Membres
** Modificateurs d'accès
** Héritage
** Encapsulation
** Polymorphisme
** Classes abstraites
** Interfaces
** Classes internes
** Transtypage
** Types génériques
** Instanciation et cycle de vie
** « this »
** Objets comparables et clés
** Énumérations
** Exceptions
** Packages
* Classes de base
** Collections
** Nombre de taille arbitraire
** Tags Javadoc
** Annotations
** Entrées sorties
** Threads et synchronisation
** Méthodes natives
** Réflexion
** Regex
** JUnit
* Conclusion
* Exemples en Java
** Générer un carré magique
** Générer un triangle de Sierpiński
** XML
** Swing
*** Un premier exemple
*** Formulaire avec boutons sur image
*** Calcul de somme
*** Calcul de distance
* Annexes
** Les outils de base fournis avec le Java Development Kit
** Créer une archive Java
** Paramétrer la JVM
** Liste des mots réservés
** Débogage
** Java et les autres langages
[ Modifier le sommaire ]
Le JDK est un ensemble d'outil permettant de développer en Java.
Pour obtenir la liste des options d'un outil, il suffit de lancer l'outil sans aucun argument.

## Compiler le code

javac est le compilateur qui convertit le code source .java en fichier .class (contenant le bytecode Java).
Supposons que vous avez :
* un dossier « src » qui contient vos sources (tous vos fichiers .java) ;
* un dossier « bin » où vous placerez tous les fichiers compilés (les fichier .class correspondant).
Si la compilation échoue parce que votre code utilise des classes que javac ne connait pas (erreur Unable to find symbol), vous devez préciser à javac un classpath comme expliqué plus loin.

## Lancer l'application

java permet une dans lancer une application java en ligne de commande, il faut passer en paramètre le nom complet (pleinement qualifié) de la classe.
La ligne de commande ci-dessus appel la méthode public static void main(String args) de la classe Exemple du package org.wikibooks.fr avec args, un tableau à deux éléments : "argument_1" et argument_2".
javaw permet une application Java sans console (interface graphique seule).
Une archive java (*.jar) avec l'option -jar, un petit fichier (appelé « Manifest ») contenu dans le jar indique lui-même le nom de la classe principale à lancer.

### Préciser le CLASSPATH

Dans toutes les commandes ci-dessus, il faut permettre à java de trouver tous les fichiers compilés nécessaire à l'exécution du code (les fichiers *.class générés avec javac). Pour cela, il faut préciser à java les répertoires ou celui-ci pourra trouver les classes et les packages nécessaires à l'application.
Pour cela, il faut définir ce qu'on appelle le « CLASS PATH », c'est une simple chaîne qui définit plusieurs chemins pour trouver des .class séparés par ":" sous Linux ou ";" sous Windows. Les chemins peuvent être des chemins vers des fichiers .jar ou vers des répertoires contenant des fichiers .class. Il y a deux façons de préciser le CLASSPATH à java, la première est d'utiliser le paramètre -classpath de ligne de commande.
Sous Linux, les chemins sont séparés par le caractère deux-points :
Sous Windows, les chemins sont séparés par le caractère point-virgule :
Ici, java essaiera de trouver le fichier Exemple.class dans les deux jars donnés puis dans le dossier bin. Si le fichier n'est trouvé dans aucun de ces éléments, il y aura une erreur (Class not found exception).
La seconde façon de préciser le CLASSPATH est de définir une variable d'environnement système. Sous Linux :
Sous Windows :
Attention à ne pas confondre java -jar fichier.jar et java -cp fichier.jar, la première commande permet de lancer le programme qui se trouve dans fichier.jar et fonctionne ; la seconde précise que des classes peuvent être chargée depuis fichier.jar mais oublie de préciser quelle classe il faut lancer : java indiquera qu'un paramètre est manquant. Enfin, sachez que vous pouvez remplacer « -classpath » par « -cp ».

## jar

L'outil jar permet de regrouper les classes (fichiers *.class) et ressources d'une application en une seule archive exécutable. Cette archive est au format ZIP mais possède l'extension .jar. Dans cette archive, un répertoire spécial situé à la racine nommé META-INF contient des fichiers d'information et de configuration pour la machine virtuelle Java, dont notamment le fichier MANIFEST.MF (fichier manifest, MF = Meta File).
Une archive JAR peut être exécutable si la classe principale (contenant une méthode statique nommée main) de l'application est spécifiée dans ce fichier MANIFEST.MF. Dans ce cas, l'application peut se lancer avec la commande suivante :
Ce fichier manifest est au format texte. Exemple :
Il possède différents champs. Chaque champ possède un nom, suivi de deux-points et de sa valeur. Si une valeur est longue, elle peut être répartie sur plusieurs lignes, chaque ligne additionnelle commençant alors par au moins un caractère espace.
Pour plus de détails sur les fichiers manifest voir http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
Le champ Class-Path dans une archive JAR diffère du paramètre classpath passé aux outils Java :
* Il ne peut contenir que des chemins relatifs à d'autres archives Java (*.jar) ; les répertoires ne sont pas supportés ;
* Le séparateur est un caractère espace. Les fichiers référencés ne peuvent donc en contenir dans leur nom.
Pour créer une archive JAR à partir d'un répertoire contenant les classes et ressources (les sous-répertoires devant correspondre aux packages), et d'un fichier texte pour le fichier manifest :
Quel que soit le nom et l'extension du fichier source pour le manifest, il sera nommé MANIFEST.MF dans l'archive.
Les arguments de la commande sont décrits ci-dessous :

### cfm

    Une série de caractères dont le premier spécifie l'action principale :
   * c Créer une archive (Create).
   * t Afficher le contenu de l'archive (Table of content).
   * x Extraire les fichiers de l'archive (eXtract files).
   * u Mettre à jour l'archive existante (Update archive).
    Les caractères suivants donne l'ordre des arguments qui suivent :
   * f Le nom du fichier archive (archive File).
   * m Le nom du fichier manifest à utiliser (Manifest file).

### mon_archive.jar

    Le nom du fichier archive.

### mon_manifest.txt

    Le nom du fichier manifest à utiliser.

### -C répertoire

    Précise le chemin du répertoire pour les chemins relatifs
    Inclus le fichier spécifié (. désignant le répertoire courant sous la plupart des systèmes d'exploitation).
Eclipse possède une interface interactive pour générer un fichier JAR à partir des classes d'un projet Java, ou d'une configuration d'exécution.

## javadoc

L'outil javadoc est le générateur de documentation, qui génère automatiquement de la documentation à partir des commentaires du code source.
Voir le chapitre sur les commentaires pour plus de détails sur l'outil et son utilisation.

## jdb

Le JDK fournit un débogueur nommé jdb (Java DeBugger) utilisable depuis la ligne de commande.

### Mode interactif

Lancez la ligne de commande jdb pour accéder au débogueur interactif :
* Entrez version pour obtenir les versions de l'outil et de Java,
* Entrez help pour obtenir la liste des commandes disponibles,
* Entrez exit pour quitter le débogueur.

### Ligne de commande

Pour les options de la ligne de commande, entrez la commande jdb -help

### Déboguer une classe

Cette section montre le débogage d'une classe simple :
Après compilation de la classe, la ligne de commande pour lancer de débogueur est la suivante, en supposant que les fichiers sources dans un sous-répertoire nommé src et le code compilé dans un sous-répertoire nommé bin :
Beaucoup de commandes ne sont pas disponibles tant que la JVM n'est pas lancée :
Lancez la classe spécifiée en ligne de commande :
L'application a été exécutée et s'est terminée, et le débogueur a quitté également. Le débogueur n'est utilisable que durant l'exécution de l'application, que son exécution soit active ou suspendue soit par un point d'arrêt soit par une exécution pas à pas.

### Point d'arrêt et pas à pas

La pose d'un point d'arrêt peut se faire par la commande stop in qui a besoin du nom de la classe (paquetage inclus) et de la méthode.
Posez ensuite un point d'arrêt à l'entrée de la méthode main et lancez l'exécution :
Les commandes testées auparavant sont désormais disponibles :
Exécutez ensuite l'application pas à pas avec la commande step pour exécuter la ligne de code suivante en entrant dans les méthodes appelées, ou la commande next pour ne pas entrer dans les méthodes appelées. À chaque pas, vous pouvez afficher la valeur des variables locales, évaluer une expression, ...
* La commande where affiche la pile des appels du thread courant,
* La commande list liste le code en cours d'exécution du thread courant.
Après un point d'arrêt ou un pas d'exécution, pour continuer l'exécution jusqu'à la fin ou le prochain point d'arrêt, utiliser la commande cont (continue).

## javah

javah permet de générer un fichier d'en-tête C (*.h) contenant la déclaration des fonctions correspondantes aux méthodes natives de la classe compilée spécifiée.
    Pour plus de détails voir : Développer en Java/Faire appel à du code natif.

## javap

javap permet de lister les membres et désassembler la classe compilée spécifiée.

### Options
#### --help

    Afficher les options possibles.

#### -version

    Information de version.

#### -verbose

    Afficher toutes les informations supplémentaires.

#### -l

    Afficher les numéros de ligne et les tables de variables locales.

#### -public

    N'afficher que les classes et membres publics.

#### -protected

    Afficher les classes et membres publics ou protégés.

#### -package

    Afficher les classes et membres publics, protégés ou paquetage (par défaut).

#### -private

    Afficher toutes les classes et tous les membres.

#### -c

    Désassembler le code.

#### -s

    Afficher les signatures des types internes.

#### -sysinfo

    Afficher les informations systèmes (chemin, taille, date, MD5) des classes traitées.

#### -constants

    Afficher les constantes finales et statiques.

#### -cp chemin

    Spécifier le chemin où trouver les classes.

#### -bootclasspath chemin

    Redéfinir le chemin des classes bootstrap.

### Exemple avec désassemblage du code

La classe désassemblée dans cet exemple est produite à partir de ce fichier source :
L'option verbose permet d'afficher toutes les informations sur le fichier .class :

#### Informations générales

La première partie indique la version de java utilisée pour compiler la classe (52.0 supportée par Java 8). La classe est publique (ACC_PUBLIC) et a une classe de base (ACC_SUPER) ; seule la classe java.lang.Object n'en a pas.

#### Pool de constantes

Les constantes litérales sont regroupées en un seul endroit du fichier de classe et numérotées. Elles proviennent du code source mais aussi des constantes implicites utilisées en interne, comme par exemple le nom de la classe de base java/lang/Object quand aucune n'est spécifiée explicitement.
Chaque constante a un type (Class, Utf8, Methodref) et une ou deux valeurs associés. La valeur peut faire référence à d'autres constantes définies ailleurs, auquel cas la référence est suivi d'un commentaire donnant la valeur référencée.
Quelques types de constantes :
| Type | Description |
| Utf8 | Chaîne de caractères encodées en UTF-8. |
| String | Référence à une chaîne de caractères (Utf8) initialisant un objet de type java.lang.String. |
| Class | Référence à une chaîne de caractères (Utf8) donnant un nom de classe. |
| NameAndType | Références à une chaîne de caractères (Utf8) donnant un nom de membre et à une autre chaîne de caractères donnant la signature de son type. |
| Methodref | Références à une classe (Class) et un de ses membres (NameAndType) méthode de la classe. |
| Fieldref | Références à une classe (Class) et un de ses membres (NameAndType) attribut de la classe. |

#### Code des méthodes

Le code de chaque méthode (bytecode) de la classe est affiché, comme celui du constructeur de la classe pour l'exemple ci-dessous :
Aucun constructeur n'est pourtant déclaré dans le code source de l'exemple plus haut, mais le compilateur en a généré un par défaut.
Le nom du constructeur en interne est en fait <init>. L'indicateur d'accès ACC_PUBLIC signifie que ce constructeur est public. Le descripteurV indique que le constructeur n'a pas d'argument (parenthèses vides) et ne retourne rien (V = void).
Le code a besoin d'un élément de pile, d'une variable locale, et utilise un argument implicite (this) référençant l'objet créé à initialiser.
Le constructeur effectue dans l'ordre :
* (adresse 0, instruction codée sur 1 octet) Charge l'argument 0 (this) dans la pile (push)
* (adresse 1, instruction codée sur 3 octets) Appeler la méthode <init> (le constructeur) de la classe de base (java.lang.Object par défaut) sur l'objet référencé par l'élément au sommet de la pile.
* (adresse 4, instruction codée sur 1 octet) Retour de méthode (aucune valeur de retour).
L'instruction à l'adresse 0 correspond à la ligne 7 dans le code source, mais comme ce constructeur a été généré implicitement, la ligne source correspond à la déclaration de la classe. Une option du compilateur permet de ne pas générer la table des lignes source LineNumberTable.
Le constructeur utilise une variable locale (slot 0) nommée "this", dont le scope va de l'adresse 0 à l'adresse 5, de type Addition.
Pour la méthode somme :
La méthode est publique et statique (pas de référence this en argument implicite), prend deux arguments de type java.lang.Integer et sa valeur de retour est du même type, comme indiqué par la signature de méthode (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;.
La méthode utilise deux emplacements dans la pile, deux variables locales, et a deux arguments.
En regroupant par ligne de code source :
| Lignes sources | Code source | Assembleur bytecode | Description |
| Ligne 11 (adresses 0 à 5) | if (a==null) return b; | 0: aload_0 1: ifnonnull 6 4: aload_1 5: areturn | Charger l'argument 0 (a) dans la pile ; Dépiler la référence, si elle est non nulle, aller à l'adresse 6 ; Charger l'argument 1 (b) dans la pile ; Dépiler la référence et l'utiliser comme valeur de retour (fin de la méthode). Remarque : les instructions sont préfixées par le type manipulé (a pour les références, i pour les entiers, ...). |
| Ligne 12 (adresses 6 à 11) | if (b==null) return a; | 6: aload_1 7: ifnonnull 12 10: aload_0 11: areturn | Charger l'argument 1 (b) dans la pile ; Dépiler la référence, si elle est non nulle, aller à l'adresse 12 ; Charger l'argument 0 (a) dans la pile ; Dépiler la référence et l'utiliser comme valeur de retour (fin de la méthode). Remarque : instructions similaires à la ligne source précédente. |
| Ligne 13 (adresses 12 à 25) | return a + b; | 12: aload_0 13: invokevirtual #16 // Method java/lang/Integer.intValue:I 16: aload_1 17: invokevirtual #16 // Method java/lang/Integer.intValue:I 20: iadd 21: invokestatic #22 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 24: areturn | Charger l'argument 0 (a) dans la pile ; Dépiler l'objet référencé, appeler sa méthode intValue retournant un entier, mis dans la pile ; Charger l'argument 1 (b) dans la pile ; Dépiler l'objet référencé, appeler sa méthode intValue retournant un entier, mis dans la pile ; Additionner les deux entiers dépilés du haut de la pile et empiler le résultat ; Appeler la méthode statique Integer.valueOf pour convertir l'entier dépilé en objet, placé sur la pile ; Retourner la référence dépilée du haut de la pile. |
La méthode utilise deux variables locales nommées a et b dont la portée va des adresses 0 à 25 (tout le code de la méthode).
L'attribut de méthode StackMapTable facilite la vérification des types des valeurs dans les tables de variables locales et la pile lorsque le code contient des sauts d'instructions comme dans cet exemple. Sans cette information, la vérification de code, ne pouvant pas se fier aux instructions qui précédent seulement pour vérifier la cohérence, doit parcourir tous les chemins d'exécution possible, ce qui prendrait du temps.

## Voir aussi

* Développer en Java/Faire appel à du code natif
* Développer en Java/La machine virtuelle Java (JVM)#Le byte code