Static variable initialization order
1. Simple rules
First, let’s look at the most common JAVA code:
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++; }}Here is a guess what the output result of the console is?
OK, maybe you have guessed the result below, so you are still familiar with Java.
Copy the code as follows: 0 1
If you don't understand why the above result is output, then I'll tell you.
Java static variable initialization follows the following rules:
After reading this, you will understand that the value of Test.a has changed three times.
Set to 0 when declared>>Test1::Test1 is set to 1>>Test.a is initialized to 0
2. Complex rules
If you understand this, please look at the code below.
public class A{ public static int b = Ba; 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, Ab="+Ab); System.out.println("A::A, A.finalInt="+A.finalInt); System.out.println("A::A, Ba="+Ba); 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, Ab="+Ab); System.out.println("main, Bt="+Bt); System.out.println("main, Ca="+Ca); }}class B{ public static int t = Aa; 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, Ba="+Ba); System.out.println("B::B, Aa="+Aa); System.out.println("B::B, Ap="+Ap); System.out.println("B::B, A.plus="+A.plus); System.out.println("B::B, A.finalInt="+A.finalInt); System.out.println("B::B, A.finalInt="+A.finalInt); System.out.println("B::B, A.finalInt="+A.finalInt); 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");}Can you still guess the output result? I wrote it while testing, so I didn't guess it. Haha
The console output result is:
----------- begin A::A ----------------A::A, from=BA::A, Ab=0A::A, A.finalInt=0A::A, Ba=0A::A, B.plus=null----------- end A::A --------------------------- begin A::A ----------------A::A, from=AA::A, Ab=1A::A, A.finalInt=0A::A, Ba=1A::A, B.plus=A@a90653----------- end A::A --------------------------- begin B::B ----------------B::B, from=AB::B, Ba=1B::B, Aa=0B::B, Ap=nullB::B, A.plus=A@1fb8ee3B::B, A.finalInt=61B::B, A.finalInteger=nullB::B, A.finalStr=finalStr----------- end B::B ----------------main, Ab=1main, Bt=0----------- begin A::A ----------------A::A, from=CA::A, Ab=1A::A, A.finalInt=61A::A, Ba=1A::A, B.plus=A@a90653----------- end A::A --------------------main, Ca=A@61de33
You didn't guess this result, haha.
It takes a lot of time to explain the execution results of the program one by one. Here we will directly write down the rules followed by Java static variable initialization.
The rules in the first paragraph are still valid, but they are not sound.
Initialization of static data
Adding static-qualified fields is the so-called class field, which means that the owner of this field is not an object but a class. No matter how many objects are created, there is only one copy of static data.
The static field is always initialized in the class and then the general field is initialized. Then initialize the constructor. However, if an object of this class is not created, the object will not be initialized and will only be executed once.
As in the following code, in the StaticInitialization class, static Table table = new Table(); first, and then the Table object will not be initialized, otherwise it will not be initialized.
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();}Output:
Bowl(1)Bowl(2)Table()f1(1)Bowl(4)Bowl(5)Bowl(3)Cupboard()f1(2)Creating new Cupboard() in mainBowl(3)Cupboard()f1(2)Creating new Cupboard() in mainBowl(3)Cupboard()f1(2)f2(1)f3(1)
The displayed static initialization (that is, static blocks)
Putting multiple initialization statements in a static brace is called a static block. In fact, it is written together by writing multiple statics, and the essence is the same. Executes only when the object is created for the first time or the field of the class is accessed for the first time, and only once.
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)}Output:
Inside main()Cup(1)Cup(2)f(99)
Non-static instance initialization
There is nothing to say about this, it is just ordinary initialization, executed in order, and can be executed multiple times.
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"); }}Inside main()Mug(1)Mug(2)mug1 & mug2 initializedMugs()new Mugs() completedMug(1)Mug(2)mug1 & mug2 initializedMugs(int)new Mugs(1) completed