当使用静态引用创建对象时,为什么实例阻塞&默认构造函数在静态块之前执行?

时间:2015-09-24 05:42:07

标签: java static-block

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");
    }

}

通常在类加载期间首先执行静态块。执行上面的示例时,会收到以下输出:

  

在Test的实例块中

     

测试的默认构造函数

     

静态测试块

     

在Test的实例块中

     

测试的默认构造函数

     

在TestLab的静态块中

为什么Test类的实例块和Default Constructor在Test Class的静态块之前执行?

3 个答案:

答案 0 :(得分:7)

确定。在类初始化期间设置/执行cookie session个字段/块。 它们按照它们在代码中出现的顺序执行。 因此,在加载类static之后,当它被初始化时,会发生以下情况:

  1. TestLab ==> 被称为类static Test aStatic=new Test();的初始化的一部分。从这里开始,引用了TestLab类。因此,控制权转移到Test类。

  2. Test ==>即,执行Test类的第一行(在其初始化阶段)。这一行涉及创建static Test ref=new Test();的新实例,因此控件移动到Test的实例块(在测试的实例块中),然后移到构造函数(默认构造函数)测试)。

  3. 现在Test已完成,因此,static Test ref=new Test();的类初始化将继续并到达静态块(静态测试块)。这样就完成了Test

  4. 的初始化
  5. 控件返回Test,现在调用TestLab。再次打印测试的实例块和测试的默认构造函数(类已经初始化,因此new Test()字段不会再次初始化,静态块也不会执行)。

  6. 控件到达static的静态块(在TestLab的静态块中)。

答案 1 :(得分:1)

初始化类型时,将按文本顺序执行所有静态初始值设定项和所有静态字段初始值设定项。来自JLS 12.4.2

  

接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就像它们是单个块一样。

换句话说,执行此代码:

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

第一行创建一个实例......这需要运行实例初始化程序。所有这些实例初始化都发生在控制返回到类型初始化部分之前 - 即在静态初始化程序的行运行之前。

如果在静态初始化程序之后将字段声明移动到,则会看到相反的结果。

答案 2 :(得分:0)

通常会按照定义的顺序初始化static variables/blocks,此处您已将aStatic标记为static。它将尝试通过调用构造函数来创建Test实例,但是当提供实例块时,它将被执行,然后是构造函数,最后是静态块。