Grande question. Ce que vous voulez savoir, c'est comment Java initialiser les objets - et il y a un certain nombre d'étapes à franchir.
Je sais que le constructeur est aussi une méthode (je me trompe peut-être).
Presque à droite. Le Constructeur est une méthode spéciale. Si vous décompilez un fichier de classe, vous verrez que les constructeurs sont renommés en <init>
. <init>
est traitée différemment des autres méthodes et, par exemple, ne peut pas être appelée explicitement sauf par l'utilisation du mot-clé new
ou super
. Cette fonction est si fondamentale qu'elle est mise en œuvre dans la JVM elle-même plutôt que d'être définie dans le langage Java.
Combien de nombre d'objets sont créés dans ce cas.
Un objet est créé - une instance de C
.
C
est en outre et simultanément une instance de B
et une instance de A
et aussi Object
.
Si un objet est créé alors comment en interne super()
appelle le constructeur de la classe Parent . Comment Super est capable d'appeler le constructeur de la classe parent.
C'est là que nous entrons dans l'initialisation - l'initialisation est la façon dont la JVM crée une nouvelle instance d'un objet et définit toutes les valeurs des membres - celles de la classe spécifique et celles des superclasses. Plusieurs étapes sont nécessaires :
-
Charger toutes les classes référencées et initialiser ces classes. L'initialisation des classes n'est pas triviale en soi, je ne l'aborderai donc pas ici. Elle vaut la peine d'être lue.
-
Allouer un morceau de mémoire pour contenir les membres de l'instance, qui inclura tous les membres de l'instance. A
, B
et C
. NOTE cela explique un aspect de votre question : comment les constructeurs de la classe de base et de ses sous-classes peuvent-ils mettre à jour ou faire référence au même objet ? tous les membres de l'instance de toutes les classes sont stockés les uns après les autres dans le même morceau de mémoire. .
-
Initialiser tous les membres à leur valeur par défaut . Par exemple, int
et float
seront fixés à 0 et 0.0f.
-
Exécuter ou calculer les initialisateurs des membres, par exemple :
private int a = 10;
private int b = a * 5;
private String c = Singleton.getInstance().getValue();
-
Notez (1) que l'initialisation des membres se produit strictement dans l'ordre où les membres sont déclarés dans la classe. Cela signifie que les références aux membres plus tard dans la déclaration sont brisées :
private int a = b * 5; // Forward reference; won't compile
private int b = 10;
-
Notez (2) qu'il existe en Java une fonction sous-utilisée permettant d'exécuter un code arbitraire pour initialiser des valeurs. avant le constructeur est exécuté. Ces blocs de code sont exécutés à ce moment-là à nouveau strictement dans l'ordre de déclaration :
private int a;
private int b = 1;
{
// Initization occurs after b but before c.
// c cannot be referenced here at all
int i = SomeClass.getSomeStatic();
a = i * 2;
}
private int c = 99;
-
Exécutez le constructeur de C
. Les constructeurs doivent soit invoquer directement un constructeur de la superclasse, soit le compilateur ajoutera automatiquement l'option super()
comme première ligne du constructeur. Cela signifie que les constructeurs sont strictement exécutés dans l'ordre :
Object
A
B
C
L'objet est maintenant initialisé et est prêt à être utilisé. Vous pouvez faire des choses dangereuses si vous initialisez une valeur en utilisant des méthodes d'instance :
public class Wrong {
int a = getB(); // Don't do this!
int b = 10;
public int getB() {
return b;
}
}
Ici, a
est initialisé à 0
. En effet, au moment où getB()
est invoquée, Java a effacé la valeur de l'élément b
à la valeur par défaut ( 0
), mais ne l'a pas encore réglé sur 10
dans la deuxième phase d'initialisation.
En résumé, il n'y a qu'un seul objet et il est créé et initialisé en plusieurs étapes. Pendant ces étapes, l'objet n'est, par définition, pas complètement défini.