Java - Object Initialization Order

Posted by mikesta707 on Wed, 10 Jul 2019 00:15:20 +0200

I. The Concept of Code Block

Before exploring the order of object initialization, let's look at the concept of code blocks through code.

class  Test{
    public static String str1;  //Static field

    public String str2;         //Common field

    static{                     
        //Static code block
    }

    {
        //Construct code blocks
    }

    public Test() {  
        //Constructor
    }
}

2. Initialization order of objects when creating subclass objects

1. The sequence of field initialization, code block and constructor execution

Let's look at the code and the results first.

public class CodeBlockTest {

    public static void main(String[] args) {
        Child child = new Child();
    }

}

class Father {
    public static String fatherStr1 = "fatherStr1(Static field initialization values)";

    public String fatherStr2 = "fatherStr2(Field initialization values)";

    static {
        System.out.println("The parent static code block:" + fatherStr1);
        fatherStr1 = "fatherStr1(Static code block assignment)";
    }

    {
        System.out.println("The parent constructor block:" + fatherStr2);
        fatherStr2 = "fatherStr2(Construct block assignment)";
    }

    public Father() {
        System.out.println("The parent constructor block:" + fatherStr2);
        fatherStr2 = "fatherStr2(Constructor assignment)";
    }
}

class Child extends Father {

    public static String childStr1 = "childStr1(Static field initialization values)";

    public String childStr2 = "childStr2(Field initialization values)";

    static {
        System.out.println("Subclass static code block:" + childStr1);
        childStr1 = "childStr1(Static code block assignment)";
    }

    {
        System.out.println("Subclasses construct code blocks:" + childStr2);
        childStr2 = "childStr2(Construct block assignment)";
    }

    public Child() {
        System.out.println("Subclass constructor:" + childStr2);
        childStr2 = "childStr2(Constructor assignment)";
    }
}

//    Output results:
//    Parent static code block: fatherStr1 (static field initialization value)
//    Subclass static code block: childStr1 (static field initialization value)
//    Father class constructor block: fatherStr2 (field initialization value)
//    Father class constructor block: fatherStr2 (constructor block assignment)
//    Subclass construction code block: childStr2 (field initialization value)
//    Subclass constructor: childStr2 (constructor block assignment)

By each execution of a code block or constructor, output the value of the field after the execution of the previous code block, in order to explore the initialization order of the object.
From the current output results, we can draw the following conclusions for the initialization order of objects:
1. Static field initialization of parent class
2. Initialization of parent static code blocks and subclass static fields (next explore the order of the two)
3. Subclass static code block
4. Common field initialization of parent class
5. Parent class constructs code blocks
6. Parent class constructor
7. Common field initialization of subclasses
8. Subclasses construct code blocks
9. Subclass constructors

2. Execution order of static code block initialization of parent class and static field initialization of subclass

Again, we explore the order of execution between the two through the results of code execution.

public class CodeBloacTest2 {

    public static void main(String[] args) {
        Child child = new Child();
    }

}


class Father {
    public static String fatherStr = "(Static field initialization values)";

    static {
        System.out.println("The parent static code block: fatherStr" + fatherStr);
        fatherStr = "(Static code block assignment)";
    }
}

class Child extends Father {

    public static String childStr = fatherStr;

    static {
        System.out.println("Subclass static code block: childStr = fatherStr" + childStr);
        childStr = "(Static code block assignment)";
    }
}

//    Output results:
//    Parent static code block: fatherStr (static field initialization value)
//    Subclass static code block: childStr = fatherStr (static code block assignment)

When we initialize the static field childStr of the subclass, we assign the value of fatherStr of the static field of the parent class. The output shows that the initialized value of childStr is the value given to fatherStr by the static code block of the parent class after execution. From this we can see that the execution order of the two is: static code block of parent class==> static field initialization of child class.

III. CONCLUSION

  1. Parent static field initialization
  2. Parent static code block
  3. Subclass static field initialization
  4. Subclass static code block
  5. Parent Class Common Field Initialization
  6. Parent class constructs code blocks
  7. Parent constructor
  8. Class Common Field Initialization
  9. Subclasses construct code blocks
  10. Subclass constructor

From the conclusion, we can clearly see that the execution order of static field and code block is prior to that of non-static field and code block. This is because static domains belong to classes and always exist after classes are loaded, while common domains need to create objects to access them. When creating an object, you need to load the parent class first and then the subclass, so the static field initialization and static code block execution of the parent class precede the subclass.