I. Initialization of java objects
The first step is to load the class. A java object loads the class before initialization and generates the class object in the JVM. Loading a class does the following, which is described recursively below. (See Reflection for more details on Class objects Click here)
If the class has a parent, the parent class is loaded first.
i Initialize this class of static members
ii executes this kind of static code block
The second step is to create an object. If the class has a parent class, the object of its parent class will be created first. The attributes and methods of the child class will be wrapped in the outer layer, and then the reference of the child class will be returned. The recursive description is given below.
If the class has a parent class, create the object of the parent class first.
i Initializes this class of ordinary members.
ii executes common code blocks.
iii calls this class of constructors.
Case Testing
This class of objects acts as member variables
public class Info{ public Info(String s) { System.out.println(s); } }
Parent class
public class Parent { public static Info info = new Info("Parent static member"); //Static member public Info info2 = new Info("Parent common member"); //Ordinary members static { //Static code block System.out.println("parent static block"); } { //Ordinary code block System.out.println("parent common block"); } public Parent() { //Parent Class Construction Method System.out.println("Parent.Parent()"); } }
Subclass
public class Child extends Parent{ public static Info info = new Info("Child static member"); //Static member public Info info2 = new Info("Child common member"); //Ordinary members static { //Static code block System.out.println("Child static block"); } { //Ordinary code block System.out.println("Child common block"); } public Child() { //Subclass Construction Method System.out.println("Child.Child()"); } }
In the following test class loading process, instead of creating objects, we load classes directly and are loading subclasses
public class InitObjectTest{ public static void main(String[] args) { try{ //Class.forName("Parent"); Class.forName("Child"); }catch(Exception e){ } //System.out.println("=============== now , we create an Object below ==========="); //new Parent(); } }
Test results:
The test results conform to the rules of loading classes written above. First, the static members of the parent class are initialized, then the static blocks of the parent class are executed, then the static members of the subclass are initialized, and finally the static blocks of the subclass are executed. We can see that static members do initialize when classes are loaded.
Note: Classes are loaded only once, and then objects are created without class loading, which is why static code blocks are only executed once.
Next, separate parent loading from creating parent objects, and observe the test results
public class InitObjectTest{ public static void main(String[] args) { try{ //Class.forName("Parent"); Class.forName("Parent"); }catch(Exception e){ } System.out.println("=============== now , we create an Object below ==========="); new Parent(); } }
Test results:
The test results conform to the above rules. We first show that the Parent class is loaded, so there is no additional class loaded later when the new Parent () is loaded. When creating an object, the ordinary member is initialized first, then the common code block is executed, and finally the construction method is invoked.
Subclasses are added below for testing.
public class InitObjectTest{ public static void main(String[] args) { try{ //Class.forName("Parent"); //Class.forName("Parent"); }catch(Exception e){ } System.out.println("=============== now , we create an Object below ==========="); new Child(); } }
Test results:
When we don't show the loading class, the new object automatically loads the class. The first four lines of output are the response of the loading class. The next six lines are the response to creating objects. First, the normal members of the parent class are initialized, then the normal code blocks of the parent class are executed, then the parent class construction method is invoked, and then similar operations of the child class are performed. It fully conforms to the creation process described above.
In the following test, the parent class is loaded first, and then the child class object is created directly.
public class InitObjectTest{ public static void main(String[] args) { try{ //Class.forName("Parent"); Class.forName("Parent"); }catch(Exception e){ } System.out.println("=============== now , we create an Object below ==========="); new Child(); } }
Test results:
First, the parent class is loaded. When creating the child class object, the child class needs to be loaded. When loading the child class, the parent class needs to be loaded. The parent class has been loaded before, so it is not loaded again here.
Summary
At this point, the execution sequence between the modules of static members, static code blocks, ordinary members, common code blocks, constructors and parent classes is finished. It is very clear from the two steps of loading and creating. Each step involves the loading of the parent class, which is a recursive process. The initialization of members precedes the execution of code blocks, because code blocks may manipulate members. Code blocks are often used to initialize members.
If there are any mistakes, please point out that you are welcome to discuss and share them.