When objects created with static reference, why do instance block & default constructor get executed before static block?

和自甴很熟 提交于 2019-12-08 19:39:35

问题


public class TestLab {

    static Test aStatic=new Test();
    public static void main(String[] args) {

        TestLab obj=new TestLab();
    }
    static{
        System.out.println("In static block of TestLab");
          }

}


public class Test {


    static Test ref=new Test();
    Test()
    {
        System.out.println("Default Constructor of Test");
    }
    static
    {
        System.out.println("In Static Block of Test");
    }
    {
         System.out.println("In instance block of Test");
    }

}

Normally the static blocks are executed first during class loading. When the above example is executed, the following output is received:

In instance block of Test

Default Constructor of Test

In Static Block of Test

In instance block of Test

Default Constructor of Test

In static block of TestLab

Why does the instance block and Default Constructor of Test class gets executed before the static block of Test Class?


回答1:


Ok. static fields / blocks are set / executed during class initialization. They are executed in the order that they appear in the code. So, after class TestLab is loaded, when it is getting initialized, the following things happen :

  1. static Test aStatic=new Test(); ==> Called as part of initialization of class TestLab. From here, Test class is referenced. So, control moves to Test class.

  2. static Test ref=new Test(); ==> i.e, first line of Test class (during its initialization phase) is executed. This line involves creating a new instance of Test, so control moves to instance block (In instance block of Test) of Test and then to constructor (Default Constructor of Test).

  3. Now static Test ref=new Test(); is complete, so, the class initialization of Test continues and reaches the static block (In Static Block of Test). This completes initialization of Test.

  4. Control reaches back to TestLab, now new Test() is called. So again In instance block of Test and Default Constructor of Test are printed (class is already initialized, so static fields are not initialized again and static blocks are not executed).

  5. Control reaches static block of TestLab (In static block of TestLab).




回答2:


When the type is initialized, all the static initializers and all the static field initializers are executed, in textual order. From JLS 12.4.2:

Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

In other words, this code gets executed:

ref = new Test();
System.out.println("In Static Block of Test");

That first line creates an instance... which requires the instance initializer to be run. All of that instance initialization happens before control returns to the type initialization part - i.e. before the line from the static initializer runs.

If you move the field declaration to after the static initializer, you'll see the opposite results.




回答3:


Usually static variables/blocks will be initialized in the order they are defined, here you have marked aStatic as static. It will try to create the instance of Test by invoking constructor, but as instance block is provided it will get executed and then the constructor and eventually the static block.



来源:https://stackoverflow.com/questions/32754136/when-objects-created-with-static-reference-why-do-instance-block-default-cons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!