Pourquoi les champs statiques ne sont pas initialisées dans le temps?
Le code suivant imprime null
une fois.
class MyClass {
private static MyClass myClass = new MyClass();
private static final Object obj = new Object();
public MyClass() {
System.out.println(obj);
}
public static void main(String[] args) {}
}
Pourquoi les objets statiques non initialisées avant l'exécution du constructeur?
Mise à jour
J'avais juste copié ce programme d'exemple et sans attention, je pensais que nous parlions de 2 champs d'Objet, maintenant que j'ai vu que le premier est un MyClass champ.. :/
Vous devez vous connecter pour publier un commentaire.
À cause de la statique sont initialisés dans l'ordre où ils sont donnés dans le code source.
Check this out:
À imprimer:
MODIFIER
Ok mettons à être un peu plus clair.
Est-ce clair?
EDIT 2
Comme Varman a souligné la référence à elle-même sera nulle alors qu'elle est en cours d'initialisation. Qui a de sens que si vous pensez à ce sujet.
myClass
lui-même est statique.null null myClassObjectref null
Essayons une autre façon d'expliquer cela...
C'est la séquence de la JVM va de travers lors de la première référence de la classe
MyClass
.static { ... }
blocs.myClass
variable statique à une nouvelle instance deMyClass
.MyClass
est déjà chargé (byte-code) et dans le processus d'être initialisé, de sorte qu'il ignore l'initialisation.obj
qui est encorenull
(puisqu'il ne fait pas partie de la tas et de constructeur initialisé les variables).obj
à une nouvelle instance deObject
.obj
ne serait pasnull
mais une référence à unObject
instance.Rappelez-vous que Java spécifie qu'un
final
variable est attribuée une valeur une fois. Il n'est pas qu'il est garanti pour être affecté d'une valeur lorsque les références de code, à moins que vous vous assurez que les références de code après il est affecté.Ce n'est pas un bug. C'est la manière définie pour gérer l'utilisation de la classe au cours de sa propre initialisation. Si ce n'était pas le cas, la JVM irait dans une boucle infinie. Voir l'étape n ° 3.3 (si la JVM ne sautez pas de l'initialisation pour une classe qui est dans le processus de l'initialisation, il suffit de garder initialisation - boucle infinie).
Note que bien, tout cela se fait sur le même thread qui fait référence à la classe. Deuxièmement, la JVM garantit que l'initialisation complète avant toute autre thread n'est autorisé à utiliser cette classe.
C'est parce que Java exécute la statique de la section afin qu'il ne soit déclaré. Dans votre cas, la séquence est
Lors de la #1 est exécutée, obj n'est pas encore initialisé, de sorte qu'il imprime la valeur null. Essayez ce qui suit et vous verrez la différence:
De manière générale, il est préférable d'éviter une telle construire tous ensemble. Si vous essayez de créer un singleton, c'est comment ce fragment de code devrait ressembler à:
new MyClass()
en statique et que vous appelez le constructeurc'est parce que les champs statiques initialisée dans le même ordre défini.
@Pyrolistical
depuis l'initiale du premier champ statique myclass n'est pas entièrement construit ...le résultat que j'obtiens est
null
null
testInitialize.MyObject@70f9f9d8
null