我正在学习核心java中的静态块功能.
public class ClassResolution {
static class Parent {
public static String name = "Sparsh";
static {
System.out.println("this is Parent");
name = "Parent";
}
}
static class Child extends Parent {
static {
System.out.println("this is Child");
name = "Child";
}
}
public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Child.name);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为输出将是:
this is Parent
this is Child
Child
Run Code Online (Sandbox Code Playgroud)
但实际输出是:
this is Parent
Parent
Run Code Online (Sandbox Code Playgroud)
而且我不知道为什么.
Era*_*ran 14
由于name是在Parent类中声明的静态字段,因此在main方法中访问它(即使使用Child类名作为前缀访问它)会导致Parent类被初始化.Childclass未初始化.
因此"this is Parent"被显示(因为静态初始化块Parent被执行),"this is Child"则不会显示(因为静态初始化块Child是不执行)和打印的值name是"Parent".
这是相关的JLS参考:
12.4.类和接口的初始化
类的初始化包括执行其静态初始化程序和类中声明的静态字段(类变量)的初始化程序.
接口的初始化包括执行接口中声明的字段(常量)的初始化器.
12.4.1.发生初始化时
类或接口类型T将在第一次出现以下任何一个之前立即初始化:
T是一个类,并且创建了T的实例.
调用由T声明的静态方法.
分配由T声明的静态字段.
使用由T声明的静态字段,该字段不是常量变量(第4.12.4节).
T是顶级类(第7.6节),并且执行在词典内嵌套在T(第8.1.3节)内的断言语句(第14.10节).