Séquence d'initialisation des variables statiques
1. Règles simples
Regardez d'abord le code JAVA le plus courant :
public class Test { public static Test1 t = new Test1(); public static int a = 0; public static int b; public static void main(String[] arg) { System.out.println(Test.a); System.out.println(Test.b); } } class Test1 { public Test1() { Test.a++; Test.b++; } }
Devinez quelle est la sortie de la console
OK, peut-être avez-vous deviné le résultat ci-dessous, alors vous connaissez toujours Java.
0 1
Si vous ne comprenez pas pourquoi le résultat ci-dessus est affiché, laissez-moi vous le dire.
L'initialisation des variables statiques Java suit les règles suivantes :
Les variables statiques seront déclarées dans l'ordre de déclaration et définies à la valeur par défaut du type, mais pas attribuer la valeur initialisée.
Une fois la déclaration terminée, définissez les valeurs initialisées dans l'ordre de déclaration. S'il n'y a pas de valeur initialisée, ignorez-la.
Après avoir lu ceci, vous comprendrez que la valeur de Test.a a changé trois fois.
Défini sur 0 lorsqu'il est déclaré>>Test1::Défini sur 1 dans Test1>>Test.a est initialisé à 0
Règles complexes
Je comprends. ceci, veuillez revoir le code ci-dessous.
public class A { public static int b = B.a; public static A plus =new A("A"); public static final int finalInt = (int)(Math.random()*100); public static B p = new B("A"); public static final String finalStr = "finalStr"; public static final Integer finalInteger = new Integer(10); public static int a = 1; public static B c = null; public A(String from) { System.out.println("----------- begin A::A ----------------"); System.out.println("A::A, from="+from); System.out.println("A::A, A.b="+A.b); System.out.println("A::A, A.finalInt="+A.finalInt); System.out.println("A::A, B.a="+B.a); System.out.println("A::A, B.plus="+B.plus); System.out.println("----------- end A::A ----------------"); } public static void main(String[] arg) { System.out.println("main, A.b="+A.b); System.out.println("main, B.t="+B.t); System.out.println("main, C.a="+C.a); } } class B { public static int t = A.a; public static A plus = new A("B"); public static int a = 1; public B(String from) { System.out.println("----------- begin B::B ----------------"); System.out.println("B::B, from="+from); System.out.println("B::B, B.a="+B.a); System.out.println("B::B, A.a="+A.a); System.out.println("B::B, A.p="+A.p); System.out.println("B::B, A.plus="+A.plus); System.out.println("B::B, A.finalInt="+A.finalInt); System.out.println("B::B, A.finalInteger="+A.finalInteger); System.out.println("B::B, A.finalStr="+A.finalStr); System.out.println("----------- end B::B ----------------"); } } class C { public static final A a = new A("C"); }
Pouvez-vous encore deviner le résultat de sortie ? Je l'écrivais pendant le test, donc je ne l'ai pas deviné Haha
Le résultat de sortie de la console est :
----------- begin A::A ---------------- A::A, from=B A::A, A.b=0 A::A, A.finalInt=0 A::A, B.a=0 A::A, B.plus=null ----------- end A::A ---------------- ----------- begin A::A ---------------- A::A, from=A A::A, A.b=1 A::A, A.finalInt=0 A::A, B.a=1 A::A, B.plus=A@a90653 ----------- end A::A ---------------- ----------- begin B::B ---------------- B::B, from=A B::B, B.a=1 B::B, A.a=0 B::B, A.p=null B::B, A.plus=A@1fb8ee3 B::B, A.finalInt=61 B::B, A.finalInteger=null B::B, A.finalStr=finalStr ----------- end B::B ---------------- main, A.b=1 main, B.t=0 ----------- begin A::A ---------------- A::A, from=C A::A, A.b=1 A::A, A.finalInt=61 A::A, B.a=1 A::A, B.plus=A@a90653 ----------- end A::A ---------------- main, C.a=A@61de33Vous n'avez pas deviné ce résultat, haha.Pour expliquer le résultat de l'exécution du programme phrase par phrase, cela prend encore beaucoup de place Ici, je vais écrire directement les règles suivies par Java statique. Règles d'initialisation des variables. Les règles du premier paragraphe sont toujours valables, mais ne sont pas valables. Seulement lorsqu'une classe est activement demandée, cette classe sera initialisée et elle ne contient que des variables statiques, des fonctions et d'autres éléments statiques Dans les relations d'héritage, la classe parent est initialisée en premier. , puis la sous-classe est initialisée. Les variables statiques seront déclarées dans l'ordre de déclaration et définies à la valeur par défaut du type, mais ne se verront pas attribuer la valeur initialisée.Après la déclaration est terminée, elles seront définies dans l'ordre de déclaration. S'il n'y a pas de valeur initialisée, ignorez-la Lors de l'initialisation de A.b = B.a, mettez en pause l'initialisation de A.b, définissez le. classe actuelle vers B, passez à l'étape 3 et exécutez Lors de l'initialisation de B.plus = new A, suspendez l'initialisation de B.plus, instanciez A et attribuez-le à B.plus.Lorsque la valeur de B.a doit être obtenue dans le constructeur de A, B.a est également initialisé et Dans l'état d'initialisation en pause, prenez directement la valeur actuelle de B.a sans attendre que B.a soit initialisé final. , les constantes statiques suivent en fait l'initialisation des variables statiques ordinaires, mais au moment de la compilation, le compilateur remplacera les valeurs des constantes là où elles sont utilisées. Vous pouvez utiliser les outils de décompilation Java pour afficher Initialisation des données statiques plus les champs qualifiés statiques sont ce qu'on appelle les champs de classe, ce qui signifie que la propriété de ce champ n'est pas un objet mais une classe. Quel que soit le nombre d’objets créés, il n’existe qu’une seule copie des données statiques.
Dans une classe, les champs statiques sont toujours initialisés en premier, puis les champs généraux sont initialisés. Initialisez ensuite le constructeur. Mais si un objet de cette classe n'est pas créé, l'objet ne sera pas initialisé et ne sera exécuté qu'une seule fois.
Comme le montre le code suivant, dans la classe StaticInitialization, initialisez d'abord static Table table = new Table(); puis initialisez l'objet Table, sinon il ne sera pas initialisé.
Sortie :class Bowl { Bowl(int marker) { print("Bowl(" + marker + ")"); } void f1(int marker) { print("f1(" + marker + ")"); } } class Table { static Bowl bowl1 = new Bowl(1); Table() { print("Table()"); bowl2.f1(1); } void f2(int marker) { print("f2(" + marker + ")"); } static Bowl bowl2 = new Bowl(2); } class Cupboard { Bowl bowl3 = new Bowl(3); static Bowl bowl4 = new Bowl(4); Cupboard() { print("Cupboard()"); bowl4.f1(2); } void f3(int marker) { print("f3(" + marker + ")"); } static Bowl bowl5 = new Bowl(5); } public class StaticInitialization { public static void main(String[] args) { print("Creating new Cupboard() in main"); new Cupboard(); print("Creating new Cupboard() in main"); new Cupboard(); table.f2(1); cupboard.f3(1); } static Table table = new Table(); static Cupboard cupboard = new Cupboard(); }Initialisation statique affichée (c'est-à-dire un bloc statique)
Bowl(1) Bowl(2) Table() f1(1) Bowl(4) Bowl(5) Bowl(3) Cupboard() f1(2) Creating new Cupboard() in main Bowl(3) Cupboard() f1(2) Creating new Cupboard() in main Bowl(3) Cupboard() f1(2) f2(1) f3(1)Envelopper plusieurs instructions d'initialisation dans une accolade statique est appelé un bloc statique. , plusieurs statiques sont écrites ensemble et l'essence est la même. Il ne sera exécuté que lors de la première création de l'objet ou lors du premier accès à un champ de la classe, et une seule fois.
class Cup { Cup(int marker) { print("Cup(" + marker + ")"); } void f(int marker) { print("f(" + marker + ")"); } } class Cups { static Cup cup1; static Cup cup2; static { cup1 = new Cup(1); cup2 = new Cup(2); } Cups() { print("Cups()"); } } public class ExplicitStatic { public static void main(String[] args) { print("Inside main()"); Cups.cup1.f(99); // (1) } // static Cups cups1 = new Cups(); // (2) // static Cups cups2 = new Cups(); // (2) }
Inside main() Cup(1) Cup(2) f(99)
Initialisation de l'instance non statique
class Mug { Mug(int marker) { print("Mug(" + marker + ")"); } void f(int marker) { print("f(" + marker + ")"); } } public class Mugs { Mug mug1; Mug mug2; { mug1 = new Mug(1); mug2 = new Mug(2); print("mug1 & mug2 initialized"); } Mugs() { print("Mugs()"); } Mugs(int i) { print("Mugs(int)"); } public static void main(String[] args) { print("Inside main()"); new Mugs(); print("new Mugs() completed"); new Mugs(1); print("new Mugs(1) completed"); } }Pour plus d'articles liés à l'analyse complète de l'initialisation des variables statiques en Java, veuillez faire attention au site Web PHP chinois !
Inside main() Mug(1) Mug(2) mug1 & mug2 initialized Mugs() new Mugs() completed Mug(1) Mug(2) mug1 & mug2 initialized Mugs(int) new Mugs(1) completed