为什么在访问Child.name时没有执行Child类的静态块?

spa*_*610 8 java

我正在学习核心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节).