Java class initialization
Java provides two different initialization types: class initialization and object initialization. The class members are static and a value is set by default. Object initialization is performed in the constructor. However, if you want to assign a static variable non-default value or initialize a class of Common Object Attributes (no matter which constructor is called), you need some special methods. Static initialization blocks and non-static initialization blocks are provided to handle these two situations.
Static initialization Block
Static initialization blocks are defined through static. A simple code example is as follows:
public class CorderStatic {staticint idx;static{ System.out.println("idx: " + Integer.toString(idx++)); System.out.println("idx: " + Integer.toString(idx));}publicstatic void main(String[] argv) { System.out.println("DONE");}}
The result of code execution is:
The output result shows that the static initialization block is called after the static member is initialized. In addition, if the class contains multiple static initialization blocks, it is called according to the order in which the block appears.
Non-static initialization Block
Non-static initialization blocks are defined in {} blocks. The difference between static initialization block and static initialization block is that there is no static keyword rhetoric. The test code is as follows:
public class CorderInstance { int idx;{ System.out.println("idx: " + Integer.toString(idx++)); System.out.println("idx: " + Integer.toString(idx++));}publicCorderInstance() { System.out.println("idxin constructor : " + Integer.toString(idx));}public static void main(String[] argv) { newCorderInstance(); System.out.println("DONE");}}
The code output is as follows:
Idx: 0 Idx: 1 Idxin constructor: 2 DONE |
It can be seen that non-static initialization blocks are called before object attribute initialization ends and constructor calls.
Initialization order
If a class defines static and non-static initialization blocks, which one will be executed first? The test code is as follows:
public class Corder {static int staticpro;static{ System.out.println("staticblock : " + Integer.toString(staticpro));}int instancepro;{ System.out.println("non-staticblock." + Integer.toString(instancepro++));}publicCorder() { System.out.println("instanceproperty : " + Integer.toString(instancepro++)); System.out.println("Theconstructor had been complete.");}publicstatic void main(String[] argv) { newCorder();}}
The code output is as follows:
Staticblock: 0 Non-staticblock.0 Instanceproperty: 1 Theconstructor had been complete. |
It can be seen that the static initialization block will be called first, then the non-static initialization block, and finally the constructor.
Inheritance and initialization
Initialization blocks become more complex when class inheritance occurs. First, paste the test code:
public class CorderInherit {static int staticpro;staticA a;static{ System.out.println("staticinitialization : " + Integer.toString(staticpro)); if(a == null) { System.out.println("classa is null."); } a= new B(10);}intinstancepro;A aa;{ instancepro= 10; System.out.println("specialblock." + Integer.toString(instancepro)); aa= new B(10);}publicCorderInherit(int i) { System.out.println("instanceproperty : " + Integer.toString(instancepro)); instancepro= i; System.out.println("staticproperty : " + Integer.toString(staticpro)); System.out.println("instanceproperty : " + Integer.toString(instancepro)); System.out.println("Theconstructor had been complete.");} publicstatic void main(String[] argv) { newCorderInherit(-1); }}class A { static int index; static{ System.out.println("ClassA static 1 " + Integer.toString(index++)); } { System.out.println("ClassA special 1 " + Integer.toString(index++)); } public A() { System.out.println("constructclass A." + Integer.toString(index++)); } static{ System.out.println("classA static 2 " + Integer.toString(index++)); } { System.out.println("ClassA Special 2 " + Integer.toString(index++)); }}class B extends A { static int index; static{ System.out.println("ClassB static 1 " + Integer.toString(index++)); } { System.out.println("ClassB special 1 " + Integer.toString(index++)); } public B(int i) { System.out.println("constructclass B." + Integer.toString(index++)); } static{ System.out.println("classB static 2 " + Integer.toString(index++)); } { System.out.println("ClassB Special 2 " + Integer.toString(index++)); }}
The code output is as follows:
Staticinitialization: 0 Classa is null. ClassA static 1 0 ClassA static 2 1 ClassB static 1 0 ClassB static 2 1 ClassA special 1 2 ClassA Special 2 3 Constructclass A.4 ClassB special 1 2 ClassB Special 2 3 Constructclass B .4 Specialblock.10 ClassA special 1 5 ClassA Special 2 6 Constructclass A.7 ClassB special 1 5 ClassB Special 2 6 Constructclass B .7 Instanceproperty: 10 Staticproperty: 0 Instanceproperty:-1 Theconstructor had been complete. |
Observe the above output. We can see that when B's object is instantiated, the virtual opportunity is to load B. class, but because B inherits A, A. class will also be loaded. This causes the static initialization blocks of A and B to be called separately. When constructing objects of B, non-static initialization blocks and Default constructors of A are called, and then non-static initialization blocks and constructors of B are called.
Conclusion
The above example shows that the complete initialization sequence of the class is as follows (the subclass is the current class, or the class to be new ):
Assign default values to static members of the parent class
Call the static initialization block of the parent class in the order of appearance
Assign default value to the static member of the subclass
Call the static initialization block of the subclass in the order of appearance
Default Value of the property assigned to the parent class Object
Call the non-static initialization block of the parent class object in sequence
Call the parent class Constructor
Default value of property assigned to subclass objects
Call non-static initialization blocks of subclass objects in sequence
Call subclass Constructor