使用静态引用创建对象时,为什么实例块和默认构造函数先于静态块执行?
When objects created with static reference, why do instance block & default constructor get executed before 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");
}
}
通常静态块在class加载期间首先执行。执行上述示例时,会收到以下输出:
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
为什么测试 class 的实例块和默认构造函数在测试 Class 的静态块之前执行?
初始化类型时,将按文本顺序执行所有静态初始化程序和所有静态字段初始化程序。来自 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.
换句话说,这段代码被执行:
ref = new Test();
System.out.println("In Static Block of Test");
第一行创建一个实例...要求实例初始值设定项为 运行。所有实例初始化都发生在控制 returns 到类型初始化部分之前——即在静态初始化器 运行s.
行之前
如果将字段声明移动到 静态初始值设定项之后,您会看到相反的结果。
好的。 static
字段/块在 class 初始化期间设置/执行。 它们按照它们在代码中出现的顺序执行。
所以,在加载 class TestLab
之后,当它被初始化时,会发生以下事情:
static Test aStatic=new Test();
==>
作为 class TestLab
初始化的一部分调用。从这里开始,Test
class 被引用。因此,控制移动到 Test
class.
static Test ref=new Test();
==> 即,执行测试 class 的第一行(在其初始化阶段)。此行涉及创建 Test
的新实例,因此控制权移至 Test
的实例块(In Test 的实例块),然后移至构造函数(测试的默认构造函数)。
现在static Test ref=new Test();
完成了,所以,Test
的class初始化继续,到达静态块(In Static Block of测试)。这就完成了 Test
.
的初始化
控制返回到 TestLab
,现在调用 new Test()
。所以再次 In instance block of Test 和 Default Constructor of Test 被打印(class 已经初始化,所以 static
字段不会再次初始化,静态块也不会执行)。
控件到达 TestLab
的静态块(在 TestLab 的静态块中)。
通常static variables/blocks
会按照定义的顺序进行初始化,这里你把aStatic
标记为static
。它将尝试通过调用构造函数来创建 Test 的实例,但是当提供实例块时,它将被执行,然后是构造函数,最后是静态块。
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");
}
}
通常静态块在class加载期间首先执行。执行上述示例时,会收到以下输出:
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
为什么测试 class 的实例块和默认构造函数在测试 Class 的静态块之前执行?
初始化类型时,将按文本顺序执行所有静态初始化程序和所有静态字段初始化程序。来自 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.
换句话说,这段代码被执行:
ref = new Test();
System.out.println("In Static Block of Test");
第一行创建一个实例...要求实例初始值设定项为 运行。所有实例初始化都发生在控制 returns 到类型初始化部分之前——即在静态初始化器 运行s.
行之前如果将字段声明移动到 静态初始值设定项之后,您会看到相反的结果。
好的。 static
字段/块在 class 初始化期间设置/执行。 它们按照它们在代码中出现的顺序执行。
所以,在加载 class TestLab
之后,当它被初始化时,会发生以下事情:
static Test aStatic=new Test();
==> 作为 classTestLab
初始化的一部分调用。从这里开始,Test
class 被引用。因此,控制移动到Test
class.static Test ref=new Test();
==> 即,执行测试 class 的第一行(在其初始化阶段)。此行涉及创建Test
的新实例,因此控制权移至Test
的实例块(In Test 的实例块),然后移至构造函数(测试的默认构造函数)。现在
static Test ref=new Test();
完成了,所以,Test
的class初始化继续,到达静态块(In Static Block of测试)。这就完成了Test
. 的初始化
控制返回到
TestLab
,现在调用new Test()
。所以再次 In instance block of Test 和 Default Constructor of Test 被打印(class 已经初始化,所以static
字段不会再次初始化,静态块也不会执行)。控件到达
TestLab
的静态块(在 TestLab 的静态块中)。
通常static variables/blocks
会按照定义的顺序进行初始化,这里你把aStatic
标记为static
。它将尝试通过调用构造函数来创建 Test 的实例,但是当提供实例块时,它将被执行,然后是构造函数,最后是静态块。