为什么要执行 sub class' 静态代码?
Why is sub class' static code getting executed?
我已经编写了以下代码并为超级 class 创建了对象。
class SuperClass{
static int a=2;
static int b(){
return 2;
}
int c(){
return 2;
}
SuperClass(){
System.out.println("Super");
}
static {
System.out.println("super");
}
}
public class Sub extends SuperClass{
Sub(){
System.out.println("Sub");
}
static {
System.out.println("sub");
}
static int b(){
return 3;
}
int c(){
return 3;
}
public static void main(String ax[]){
SuperClass f =new SuperClass();
System.out.println(f.c());
System.out.print(SuperClass.b());
}
}
我查看输出结果如下:
super
sub
Super
2
2
我知道只有当 class 的对象被初始化或任何静态引用被创建时,静态块才会被执行。但是在这里,我没有对 Sub class 做任何这些。那为什么我看到 "sub" 即 sub class' 静态块输出?
因为您的 main()
方法是 Sub
的成员,所以需要为您的程序加载 class 到 运行。
I know that static block is executed only when object of the class is initialized or any static reference is made. But here, i did not make any of these to Sub class.
您的 代码没有,但为了从 main
到 运行,必须加载 Sub
。所以它的静态初始值设定项是 运行.
例如,我假设你 运行 它是这样的:
java Sub
java
工具必须加载 Sub
才能调用 Sub.main
。那是导致静态初始化程序为 运行 的静态引用(实际上是访问)。 (如果你 运行 它在 IDE 中, IDE 会做 java
工具部分,但结果是一样的。)
事情是这样的:
java
触发加载 Sub
JVM 必须加载 SuperClass
才能加载 Sub
所以我们看到它们的静态初始值设定项 运行,顺序是 (SuperClass
,然后是 Sub
):
super
sub
java
工具调用 main
main
中的代码调用 new SuperClass
:
Super
main
中的代码调用 f.c()
2
main
中的代码调用 SuperClass.b
:
2
如Holger helpfully , this is covered by the JVM specification in §5.5 - Initialization and the related §5.2 - Java Virtual Machine Startup:
Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).
A class or interface C may be initialized only as a result of:
...
If C is a class, the initialization of one of its subclasses.
If C is a class, its designation as the initial class at Java Virtual Machine startup (§5.2).
倒数第二个要点涵盖 SuperClass
,最后一个要点涵盖 Sub
。
在调用 main
时,所有的静态初始化程序都会被调用,首先在超级 class 中,然后是子 class.
这解释了您观察到的输出。
加载 class 时,静态块为 运行。通常那是因为您调用了构造函数或静态成员。在这种情况下,这是因为您执行了 main 方法(静态成员)。
旁注:
- 另一个极端情况正在调用 Class.forName(className) 来加载 class.
- 您可能还注意到基础 class 在子 class 之前加载。
我已经编写了以下代码并为超级 class 创建了对象。
class SuperClass{
static int a=2;
static int b(){
return 2;
}
int c(){
return 2;
}
SuperClass(){
System.out.println("Super");
}
static {
System.out.println("super");
}
}
public class Sub extends SuperClass{
Sub(){
System.out.println("Sub");
}
static {
System.out.println("sub");
}
static int b(){
return 3;
}
int c(){
return 3;
}
public static void main(String ax[]){
SuperClass f =new SuperClass();
System.out.println(f.c());
System.out.print(SuperClass.b());
}
}
我查看输出结果如下:
super
sub
Super
2
2
我知道只有当 class 的对象被初始化或任何静态引用被创建时,静态块才会被执行。但是在这里,我没有对 Sub class 做任何这些。那为什么我看到 "sub" 即 sub class' 静态块输出?
因为您的 main()
方法是 Sub
的成员,所以需要为您的程序加载 class 到 运行。
I know that static block is executed only when object of the class is initialized or any static reference is made. But here, i did not make any of these to Sub class.
您的 代码没有,但为了从 main
到 运行,必须加载 Sub
。所以它的静态初始值设定项是 运行.
例如,我假设你 运行 它是这样的:
java Sub
java
工具必须加载 Sub
才能调用 Sub.main
。那是导致静态初始化程序为 运行 的静态引用(实际上是访问)。 (如果你 运行 它在 IDE 中, IDE 会做 java
工具部分,但结果是一样的。)
事情是这样的:
java
触发加载Sub
JVM 必须加载
SuperClass
才能加载Sub
所以我们看到它们的静态初始值设定项 运行,顺序是 (
SuperClass
,然后是Sub
):super sub
java
工具调用main
main
中的代码调用new SuperClass
:Super
main
中的代码调用f.c()
2
main
中的代码调用SuperClass.b
:2
如Holger helpfully
Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).
A class or interface C may be initialized only as a result of:
...
If C is a class, the initialization of one of its subclasses.
If C is a class, its designation as the initial class at Java Virtual Machine startup (§5.2).
倒数第二个要点涵盖 SuperClass
,最后一个要点涵盖 Sub
。
在调用 main
时,所有的静态初始化程序都会被调用,首先在超级 class 中,然后是子 class.
这解释了您观察到的输出。
加载 class 时,静态块为 运行。通常那是因为您调用了构造函数或静态成员。在这种情况下,这是因为您执行了 main 方法(静态成员)。
旁注:
- 另一个极端情况正在调用 Class.forName(className) 来加载 class.
- 您可能还注意到基础 class 在子 class 之前加载。