
new
et tout est prêt :) Ici, nous allons parler de ce qui se passe à l'intérieur de l'ordinateur et de la machine Java lorsque nous écrivons, par exemple :
Cat cat = new Cat();
Nous en avons déjà parlé, mais au cas où nous vous rappellerions :
- Tout d'abord, la mémoire pour stocker l'objet est allouée.
- Ensuite, la machine Java crée une référence à l'objet (dans notre cas, la référence est Cat cat).
- Enfin, les variables sont initialisées et le constructeur est appelé (nous allons voir ce processus plus en détail).

public class Vehicle {
public static int vehicleCounter = 0;
private String description = "Vehicle";
public Vehicle() {
}
public String getDescription() {
return description;
}
}
public class Truck extends Vehicle {
private static int truckCounter = 0;
private int yearOfManufacture;
private String model;
private int maxSpeed;
public Truck(int yearOfManufacture, String model, int maxSpeed) {
this.yearOfManufacture = yearOfManufacture;
this.model = model;
this.maxSpeed = maxSpeed;
Vehicle.vehicleCounter++;
truckCounter++;
}
}
La Truck
classe est une implémentation d'un camion avec des champs représentant son année, son modèle et sa vitesse maximale. Maintenant, nous voulons créer un tel objet :
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
Pour la machine Java, le processus ressemblera à ceci :
-
La première chose qui se passe est que les variables statiques de la
Vehicle
classe sont initialisées . Oui, j'ai bien dit laVehicle
classe, nonTruck
. Les variables statiques sont initialisées avant l'appel des constructeurs, et cela commence dans la classe parent. Essayons de vérifier cela. Nous définissons levehicleCounter
champ de laVehicle
classe égal à 10 et essayons de l'afficher à la fois dans les constructeursVehicle
etTruck
.public class Vehicle { public static int vehicleCounter = 10; private String description = "Vehicle"; public Vehicle() { System.out.println(vehicleCounter); } public String getDescription() { return description; } } public class Truck extends Vehicle { private static int truckCount = 0; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(vehicleCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCount++; } }
Nous avons délibérément placé l'instruction println au tout début du
Truck
constructeur pour être sûr que les champs du camion n'ont pas encore été initialisés lorsquevehicleCounter
s'affiche.Et voici le résultat :
10 10
-
Une fois les variables statiques de la classe parent initialisées, les variables statiques de la classe enfant sont initialisées. Dans notre cas, il s'agit du
truckCounter
champ de laTruck
classe.Faisons une autre expérience où nous essaierons d'afficher la valeur de à
truckCounter
l'intérieur duTruck
constructeur avant que les autres champs ne soient initialisés :public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(truckCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }
Comme vous pouvez le voir, la valeur 10 a déjà été affectée à notre variable statique au
Truck
démarrage du constructeur. -
Ce n'est toujours pas l'heure des constructeurs ! L'initialisation des variables continue. Les variables non statiques de la classe parent sont initialisées en troisième. Comme vous pouvez le voir, l'héritage complique considérablement le processus de création d'un objet, mais vous n'y pouvez rien : il suffit de mémoriser certaines choses en programmation :)
À titre expérimental, nous pouvons attribuer une valeur initiale à la
description
variable dansVehicle
la classe, puis la modifier dans le constructeur.public class Vehicle { public static int vehicleCounter = 10; private String description = "Initial value of the description field"; public Vehicle() { System.out.println(description); description = "Vehicle"; System.out.println(description); } public String getDescription() { return description; } }
Exécutons notre
main()
méthode qui crée un camion :public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
Nous obtenons le résultat suivant :
Initial value of the description field Vehicle
Cela prouve que lorsque le
Vehicle
constructeur commence, ledescription
champ a déjà reçu une valeur. -
Enfin, place aux constructeurs ! Plus précisément, il est temps pour le constructeur de la classe de base. Il est appelé à la quatrième étape du processus de création d'objet.
C'est aussi assez facile à vérifier. Essayons de sortir deux lignes vers la console : une à l'intérieur du
Vehicle
constructeur de la classe de base, la seconde à l'intérieur duTruck
constructeur. Nous devons être convaincus que la ligne à l'intérieurVehicle
est affichée en premier :public Vehicle() { System.out.println("Hello from the Vehicle constructor!"); } public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Hello from the Truck constructor!"); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; }
Nous allons exécuter notre
main()
méthode et regarder le résultat :Hello from the Vehicle constructor! Hello from the Truck constructor!
Excellent. Cela signifie que nous ne nous trompons pas :) Passons à autre chose.
-
Il est maintenant temps d' initialiser les champs non statiques de la classe enfant, c'est-à-dire notre
Truck
classe. Les champs immédiatement à l'intérieur de la classe en cours d'instanciation ne sont initialisés qu'à la cinquième étape ! Surprenant, mais vrai :) Encore une fois, nous allons faire une simple vérification — comme avec la classe parent : nous donnerons une valeur initiale à lamaxSpeed
variable et dans leTruck
constructeur, nous vérifierons que la valeur a été assignée avant le démarrage du constructeur :public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed = 150; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Initial value of maxSpeed = " + this.maxSpeed); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }
Sortie console :
Initial value of maxSpeed = 150
Comme vous pouvez le voir, au démarrage du
Truck
constructeur,maxSpeed
est déjà égal à 150 ! -
Le constructeur de la
Truck
classe enfant est appelé.Et ce n'est qu'à ce stade, en dernier lieu, que le constructeur de la classe que nous instancions sera appelé !
Ce n'est qu'à la sixième étape que les champs se verront attribuer les valeurs que nous transmettons en tant qu'arguments à notre camion.
Comme vous pouvez le voir, "construire" un camion, c'est-à-dire le processus de création d'objets, n'est pas simple. Mais il semble que nous l'ayons décomposé en plus petites parties :)

GO TO FULL VERSION