Je me demande quand les variables statiques sont initialisées à leurs valeurs par défaut. Est-il correct que lorsqu'une classe est chargée, des variables statiques sont créées (allouées), puis des initialiseurs statiques et des initialisations dans les déclarations sont exécutés? À quel moment les valeurs par défaut sont-elles données? Cela conduit au problème de la référence directe.
Veuillez également si vous pouvez expliquer cela en référence à la question posée sur Pourquoi les champs statiques ne sont pas initialisés à temps? et surtout la réponse donnée par Kevin Brock sur le même site. Je ne comprends pas le 3ème point.
java
static
initialization
Ankit
la source
la source
Réponses:
À partir de See Java Static Variable Methods :
Les variables d'instance et de classe (statiques) sont automatiquement initialisées aux valeurs standard par défaut si vous ne parvenez pas à les initialiser volontairement. Bien que les variables locales ne soient pas automatiquement initialisées, vous ne pouvez pas compiler un programme qui ne parvient pas à initialiser une variable locale ou à affecter une valeur à cette variable locale avant son utilisation.
Ce que fait réellement le compilateur est de produire en interne une seule routine d'initialisation de classe qui combine tous les initialiseurs de variables statiques et tous les blocs de code d'initialisation statiques, dans l'ordre dans lequel ils apparaissent dans la déclaration de classe. Cette procédure d'initialisation unique est exécutée automatiquement, une seule fois, lors du premier chargement de la classe.
En cas de intérieur classes , elles ne peuvent pas avoir de champs statiques
Voir JLS 8.1.3 Classes internes et instances englobantes
final
les champs en Java peuvent être initialisés séparément de leur lieu de déclaration, mais cela ne peut pas s'appliquer auxstatic final
champs. Voir l'exemple ci-dessous.final class Demo { private final int x; private static final int z; //must be initialized here. static { z = 10; //It can be initialized here. } public Demo(int x) { this.x=x; //This is possible. //z=15; compiler-error - can not assign a value to a final variable z } }
En effet, il n'y a qu'une seule copie des
static
variables associées au type, plutôt qu'une copie associée à chaque instance du type comme avec les variables d'instance et si nous essayons d'initialiser lez
typestatic final
dans le constructeur, il tentera de réinitialiser lestatic final
champ de typez
car le constructeur est exécuté à chaque instanciation de la classe qui ne doit pas se produire dans lesfinal
champs statiques .la source
In case of static inner classes, they can not have static fields
semble être une faute de frappe. Les classes internes ne sont pas statiques.Voir:
Le dernier en particulier fournit des étapes d'initialisation détaillées qui expliquent quand les variables statiques sont initialisées, et dans quel ordre (avec la mise en garde que
final
les variables de classe et les champs d'interface qui sont des constantes au moment de la compilation sont initialisés en premier.)Je ne sais pas quelle est votre question spécifique sur le point 3 (en supposant que vous parlez de celui imbriqué?). La séquence détaillée indique qu'il s'agirait d'une demande d'initialisation récursive afin qu'elle continue l'initialisation.
la source
Les champs statiques sont initialisés lorsque la classe est chargée par le chargeur de classe. Les valeurs par défaut sont attribuées à ce moment. Cela se fait dans l'ordre dans lequel ils apparaissent dans le code source.
la source
L'ordre d'initialisation est:
Les détails du processus sont expliqués dans le document de spécification JVM .
la source
variable statique
la source
En commençant par le code de l'autre 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 lancera l'initialisation. Tout d'abord, la classe sera marquée comme initialisée. Ensuite, le premier champ statique sera initialisé avec une nouvelle instance de MyClass (). Notez que myClass reçoit immédiatement une référence à une instance MyClass vierge . L'espace est là, mais toutes les valeurs sont nulles. Le constructeur est maintenant exécuté et imprime
obj
, ce qui est nul.Revenons maintenant à l'initialisation de la classe: il
obj
est fait référence à un nouvel objet réel, et nous avons terminé.Si cela a été déclenché par une instruction comme: l'
MyClass mc = new MyClass();
espace pour une nouvelle instance MyClass est à nouveau alloué (et la référence placéemc
). Le constructeur est à nouveau exécuté et imprime à nouveauobj
, ce qui n'est plus nul.Le vrai truc ici est que lorsque vous utilisez
new
, comme dansWhatEverItIs weii = new WhatEverItIs( p1, p2 );
weii
est immédiatement donné une référence à un peu de mémoire annulée. La machine virtuelle Java va ensuite initialiser les valeurs et exécuter le constructeur. Mais si vous faites référence d'une manière ou d'une autreweii
avant de le faire - en le référençant à partir d'un autre thread ou en faisant référence à l'initialisation de la classe, par exemple - vous regardez une instance de classe remplie de valeurs nulles.la source
La variable statique peut être initialisée des trois manières suivantes comme suit, choisissez celle que vous aimez
ou vous pouvez le faire en créant un bloc statique, par exemple:
static { // whatever code is needed for initialization goes here }
Il existe une alternative aux blocs statiques - vous pouvez écrire une méthode statique privée
class name { public static varType myVar = initializeVar(); private static varType initializeVar() { // initialization code goes here } }
la source