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

}

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

在测试的实例块中

测试的默认构造函数

在静态测试块中

在测试的实例块中

测试的默认构造函数

在 TestLab 的静态块中

为什么测试类的实例块和默认构造函数在测试类的静态块之前执行?

4

3 回答 3

8

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

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

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

  3. 现在static Test ref=new Test();已经完成,所以,类的初始化Test继续并到达静态块(In Static Block of Test)。这样就完成了初始化Test

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

  5. 控制到达静态块TestLab在 TestLab 的静态块中)。

于 2015-09-24T05:51:37.923 回答
1

当类型被初始化时,所有的静态初始化器和所有的静态字段初始化器都按照文本顺序执行。从JLS 12.4.2开始:

接下来,按照文本顺序执行类的类变量初始化程序和静态初始化程序,或者接口的字段初始化程序,就好像它们是一个单独的块一样。

换句话说,这段代码被执行:

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

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

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

于 2015-09-24T05:49:54.940 回答
0

通常static variables/blocks会按照它们定义的顺序进行初始化,这里你已经标记aStaticstatic. 它将尝试通过调用构造函数来创建 Test 的实例,但由于提供了实例块,它将被执行,然后是构造函数,最后是静态块。

于 2015-09-24T05:51:47.587 回答