# Programmation Java/Instanciation et cycle de vie

* 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 ]
Toute variable de type objet est une référence vers une instance de classe allouée en mémoire sur le tas. La référence particulière null pointe vers une instance non allouée, et constitue la valeur par défaut des références. Il faut donc allouer une instance et l'assigner à une variable de type référence avant de pouvoir utiliser un objet et ses membres par l'opérateur de déréférencement point : objet.membre. L'opérateur de déréférencement sur une référence nulle déclenche une exception de type NullPointerException.
Un tableau est également un objet, pouvant stocker un nombre fixe d'éléments spécifié à l'instruction new.

## L'instruction new

L'instruction new permet d'instancier une classe en utilisant l'un des constructeurs de la classe.
Par exemple pour créer un objet de type MaClasse, on écrit :
Cette instruction sert également à allouer les tableaux en spécifiant le nombre d'éléments entre crochets après leur type.

## Les constructeurs

Un constructeur est une méthode particulière de la classe appelée lors de la création d'une instance de la classe. Son rôle est d'initialiser les membres de l'objet juste créé. Un constructeur a le même nom que sa classe et n'a pas de valeur de retour.
Dans l'exemple suivant la classe MaClasse dispose de deux constructeurs, l'un ne prenant aucun paramètre et l'autre prenant un paramètre de type String :
Toute classe possède au moins un constructeur. Cependant, il n'est pas obligatoire de déclarer un constructeur pour une classe. En effet, si aucun constructeur n'est déclaré dans une classe, un constructeur sans paramètre est ajouté de manière implicite. Celui-ci ne fait rien, en apparence.
Un constructeur d'objet en appelle toujours un autre :
* Soit explicitement un autre constructeur de la même classe en utilisant this,
* Soit explicitement un constructeur de la classe mère en utilisant super,
* Soit implicitement le constructeur sans arguments de la classe mère.
Ces deux derniers points ne sont pas applicables à la classe java.lang.Object racine de toutes les autres classes.
Le code ci-dessous est strictement équivalent à l'exemple précédent, avec les appels implicites mis explicitement
Quand une classe a plusieurs constructeurs qui définissent des valeurs par défaut, il vaut mieux que chaque constructeur appelle un autre constructeur de la classe. Cela permet de faciliter la maintenance en centralisant le comportement de construction et la définition des valeurs par défaut en un seul endroit du code.

## Initialisation d'un objet

L'appel à l'instruction new crée un nouvel objet de la classe spécifiée initialisé de la façon suivante :
* Juste après l'allocation mémoire, tous les membres sont initialisés à leur valeur par défaut dépendant du type (null pour les références, false pour les booléens, et 0 pour les types numériques).
* Le constructeur nommé en interne <init> correspondant aux types des arguments de l'instruction new est appelé.
Le code de chaque constructeur <init> est constitué de plusieurs parties concaténées :
* l'appel explicite au constructeur de la classe de base dans le fichier source, ou un appel implicite au constructeur par défaut (sans arguments) ;
* le code commun de construction définit par les initialisations de membres et les blocs de code non précédés du mot static
* et le code définit explicitement dans le fichier source.

### Exemple

Le code du constructeur <init>(String name) contient alors cette séquence générée par le compilateur :
Les lignes d'initialisation (de (1) à (3) pour l'exemple précédent) sont donc insérées juste après l'appel au constructeur de la classe de base, dans tous les constructeurs de la classe.
L'ordre des initialisations est très important. Dans l'exemple précédent, si les lignes (1) et (3) sont interverties, une exception de type NullPointerException est lancée lors de la construction de l'objet.
Le bloc d’initialisation ne peut pas envoyer explicitement une exception, même s'il s'agit d'une sous-classe de RuntimeException. Dans le cas contraire, le compilateur retourne l'erreur Initializer does not complete normally.
Par contre le constructeur peut en lancer :

## Initialisation d'une classe

Avant la première instanciation, la classe est initialisée par la méthode statique spéciale nommée <clinit>. Le code de cette méthode est construit par le compilateur en concaténant les instructions d'initialisations des membres statiques et des blocs de code précédés du mot static.
Il s'agit donc du même principe que les constructeurs <init> vu dans la section précédente mais appliqué aux membres statiques de la classe. Toutefois aucun code de constructeur n'est ajouté à la fin (pas de constructeur statique), et le code appelle la méthode statique spéciale <clinit> de la classe de base plutôt qu'un constructeur.

## Nettoyage
### Ramasse-miettes (Garbage Collector)

Le ramasse-miettes garde un compteur du nombre de références pour chaque objet. Dès qu'un objet n'est plus référencé, celui-ci est marqué. Lorsque le ramasse-miettes s'exécute (en général quand l'application ne fait rien), les objets marqués sont libérés.
Son exécution se produit toujours à un moment qui ne peut être déterminé à l'avance. Il s'exécute lors des évènements suivants :
* périodiquement, si le processeur n'est pas occupé,
* quand la quantité de mémoire restante est insuffisante pour allouer un nouveau bloc de mémoire.
Il est donc recommandé de libérer toute référence (affecter null) à des objets encombrants (tableaux de grande taille, collection d'objets, ...) dès que possible, ou au plus tard juste avant l'allocation d'une grande quantité de mémoire.
Exemple : Pour le code suivant, il faut 49 152 octets disponibles, le ramasse-miettes ne pouvant rien libérer durant l'allocation du deuxième tableau.
Une fois le code corrigé, il ne faut plus que 32 768 octets disponibles, le ramasse-miettes pouvant libérer le premier tableau avant d'allouer le deuxième.
Mettre à null les références devenues inutiles au plus tôt permet donc de réduire la quantité de mémoire libre nécessaire à l'allocation de tableaux ou d'objets.

### Finalisation

Lors de la libération des objets par le ramasse-miettes, celui-ci appelle la méthode finalize afin que l'objet libère les ressources qu'il utilise.
Cette méthode peut être redéfinie afin de libérer des ressources système non Java. Dans ce cas, la méthode doit se terminer en appelant la méthode de la classe parente :
Comme l'exécution du ramasse-miettes se produit toujours à un moment qui ne peut être déterminé à l'avance, l'appel à cette méthode par le ramasse-miettes n'est pas garanti. C'est pourquoi cette méthode est rarement implémentée afin d'éviter des effets de bords.

## Représentation des objets dans la mémoire

L'instruction new alloue la mémoire sur le tas pour les objets et les tableaux.
La création d'un objet de classe C qui hérite de la classe B, elle-même héritant de la classe A, se déroule à peu près de la manière suivante :
* Pour chacune des classes de la hiérarchie en partant de la classe racine (ordre A, B, C pour l'exemple), si cela n'a pas déjà été fait auparavant :
** Charger la classe (Class, code des méthodes, ...), en lui allouant également l'espace nécessaire pour ses variables membres statiques.
** Initialiser les variables membres statiques de la classe en appelant la méthode spéciale <clinit> qui contient la concaténation des assignations des membres statiques et des blocs de code statiques.
* Allocation de l'espace mémoire pour les membres d'instance de la classe C incluant les membres déclarés ainsi que ceux hérités des classes B et A.
* Appel au constructeur (méthode spéciale <init>) de la classe C correspondant aux arguments fournis en lui passant la référence à la zone mémoire allouée dans this :
** Sa première instruction est un appel explicite ou implicite à un constructeur de la classe B (lui-même appelant un constructeur de la classe A).
** Les instructions suivantes sont la concaténation des assignations des membres d'instance et des blocs de code non statiques.
** Enfin, les instructions définies explicitement dans le constructeur sont appelées.
La création d'un tableau avec l'instruction new se déroule de la même façon (sachant que tout type de tableau hérite de la classe java.lang.Object), en allouant la place nécessaire pour le type des éléments multipliée par le nombre d'éléments voulu.

### Le tas et la pile

Le tas est la zone mémoire où sont alloués les éléments de tableaux et les membres des objets. C'est une zone mémoire très grande, partagée par tous les processus légers (threads) de l'application Java. C'est pourquoi l'accès à un même objet ou tableau par plusieurs threads nécessite des moyens de synchronisation.
La pile est une zone mémoire locale limitée, alloué pour chaque processus léger (thread). Cette zone sert de stockage temporaire aux appels de méthodes pour y stocker la valeur des arguments, des variables locales, et de manière interne la valeur de retour.