L'ordre d'initialisation des classes en Java (order of class initialization) définit dans quel ordre les champs, les blocs et les constructeurs sont initialisés. En résumé :
class Parent { static { System.out.println("Parent static"); } { System.out.println("Parent init"); } Parent() { System.out.println("Parent constructor"); } } class Child extends Parent { static { System.out.println("Child static"); } { System.out.println("Child init"); } Child() { System.out.println("Child constructor"); } } // new Child() -> quel ordre ?
La sortie sera :
D'abord les blocs statiques des parents, puis les blocs statiques des enfants, puis les blocs non statiques et les constructeurs dans l'ordre de l'héritage.
Question : Quand les initialiseurs statiques seront-ils exécutés dans la classe :
class Ex {
static { System.out.println("static"); }
}
— lors de la création de la première instance ou lors de la première utilisation de n'importe quelle méthode/champ statique ?
Réponse : L'initiateur statique est exécuté lors du premier accès à la classe, y compris l'accès à n'importe quel membre statique (méthode/champ), et pas seulement lors de la création d'une instance.
Histoire
Dans une application bancaire, un pool de connexions statique était initialisé dans un bloc statique, mais en raison d'un accès à une méthode statique avant la création de la première instance, la connexion n'avait pas encore été établie. Cela a conduit à un NullPointerException sous charge.
Histoire
Le service de journalisation dépendait d'un champ non statique, qui était initialisé après l'appel au constructeur de la classe parente. Les journaux étaient écrits dans un logger null, et des messages d'erreur importants ont été perdus.
Histoire
Lors de l'ajout d'un nouveau champ avec une valeur par défaut, le développeur l'a placé après le bloc d'initialisation : le bloc a essayé d'utiliser un champ qui n'avait pas encore été initialisé, ce qui a conduit à des erreurs lors du démarrage de l'application et à une recherche difficile de la cause.