En commençant par le code de la question:
class MyClass {
private static MyClass myClass = new MyClass();
private static final Object obj = new Object();
public MyClass() {
System.out.println(obj); // will print null once
}
}
Une référence à cette classe va commencer l'initialisation. Tout d'abord, la classe sera marqué comme initialisé. Puis le premier champ statique sera initialisé avec une nouvelle instance de Maclasse(). Notez que maclasse est immédiatement donné une référence à un vide instance de Maclasse. L'espace est là, mais toutes les valeurs sont nulles. Le constructeur est maintenant exécuté et imprime obj
, qui est nulle.
Maintenant, revenons à l'initialisation de la classe: obj
est fait référence à un nouvel objet réel, et nous avons fini.
Si elle a été définie par une instruction comme: MyClass mc = new MyClass();
de l'espace pour une nouvelle instance de Maclasse est encore alloué (et la référence placée en mc
). Le constructeur est de nouveau exécutée et encore imprime obj
, ce qui maintenant n'est pas nulle.
Le vrai truc c'est que lorsque vous utilisez new
, comme en WhatEverItIs weii = new WhatEverItIs( p1, p2 );
weii
est immédiatement donné une référence à un peu de entaché de nullité de la mémoire. La JVM sera pour initialiser des valeurs et exécuter le constructeur. Mais si vous en quelque sorte de référence weii
avant qu'il ne sorte--par la référence à partir d'un autre thread ou ou par la référence à partir de la classe d'initialisation, par exemple, vous êtes à la recherche à une instance de classe rempli avec des valeurs null.