在子类中执行 Java 个静态块
Execution of Java static blocks in subclasses
我正在为 Java 认证测试做准备,我发现了一个与执行 Java 静态块相关的有趣问题。我花了很多时间阅读有关此主题的内容,但没有找到我想要的答案。
我知道当 class 加载到 JVM 或调用 main 方法时会执行静态块,但是...
package oneClassTasks;
class Parent {
static int age;
}
class Child extends Parent {
static {
age = 5;
System.out.println("child's static block");
}
}
public class XXX {
public static void main(String args[]) {
System.out.println("Child age is : "+ Child.age);
}
}
输出为:
Child age is : 0
如果我使用 -verbose:class
包含详细输出,则输出为:
...
[Loaded java.security.BasicPermissionCollection from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded oneClassTasks.XXX from file:/D:/temp/bin/]
[Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded oneClassTasks.Parent from file:/D:/temp/bin/]
[Loaded oneClassTasks.Child from file:/D:/temp/bin/]
Child age is : 0
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
我们可以在这里看到 子 class 被加载 到 JVM 中。
谁能解释一下为什么 Child
class 中的静态块没有被执行?
您看到 Child
class 已加载,但未初始化。
访问 Child.age
不会导致 Child
class 的初始化,因为 age
是 Parent
class 的成员.因此只有Parent
class被初始化,age
仍然是0
.
12.4.1. When Initialization Occurs
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:
T is a class and an instance of T is created.
A static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
T is a top level class (§7.6) and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
在您的情况下,您访问了由 Parent
声明的静态字段,因此只有 Parent
被初始化。
在这种情况下,Child.age 等同于 Parent.age。 JRE 会将其视为 Parent.age,这就是为什么只有 Parent 被静态初始化,而 Child 的静态初始化器被跳过。
我正在为 Java 认证测试做准备,我发现了一个与执行 Java 静态块相关的有趣问题。我花了很多时间阅读有关此主题的内容,但没有找到我想要的答案。
我知道当 class 加载到 JVM 或调用 main 方法时会执行静态块,但是...
package oneClassTasks;
class Parent {
static int age;
}
class Child extends Parent {
static {
age = 5;
System.out.println("child's static block");
}
}
public class XXX {
public static void main(String args[]) {
System.out.println("Child age is : "+ Child.age);
}
}
输出为:
Child age is : 0
如果我使用 -verbose:class
包含详细输出,则输出为:
...
[Loaded java.security.BasicPermissionCollection from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded oneClassTasks.XXX from file:/D:/temp/bin/]
[Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded oneClassTasks.Parent from file:/D:/temp/bin/]
[Loaded oneClassTasks.Child from file:/D:/temp/bin/]
Child age is : 0
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre1.8.0_161\lib\rt.jar]
我们可以在这里看到 子 class 被加载 到 JVM 中。
谁能解释一下为什么 Child
class 中的静态块没有被执行?
您看到 Child
class 已加载,但未初始化。
访问 Child.age
不会导致 Child
class 的初始化,因为 age
是 Parent
class 的成员.因此只有Parent
class被初始化,age
仍然是0
.
12.4.1. When Initialization Occurs
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T is a class and an instance of T is created.
A static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
T is a top level class (§7.6) and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
在您的情况下,您访问了由 Parent
声明的静态字段,因此只有 Parent
被初始化。
在这种情况下,Child.age 等同于 Parent.age。 JRE 会将其视为 Parent.age,这就是为什么只有 Parent 被静态初始化,而 Child 的静态初始化器被跳过。