Maison  >  Article  >  Java  >  Analyse complète de l'initialisation des variables statiques en Java

Analyse complète de l'initialisation des variables statiques en Java

高洛峰
高洛峰original
2017-01-24 17:03:202306parcourir

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@61de33
Vous 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.


Sortie :
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

Il n'y a rien à dire, c'est juste une initialisation normale, exécuté dans l'ordre, peut être exécuté plusieurs fois.


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
Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn