在子类中执行Java静态块

dev*_*per 6 java static jvm execution

我正准备自己进行Java认证测试,我发现了一个与Java静态块执行相关的有趣问题.我花了很多时间阅读这个主题,但我找不到我想要的答案.

我知道当类被加载到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);
    }

}
Run Code Online (Sandbox Code Playgroud)

输出是:

Child age is : 0
Run Code Online (Sandbox Code Playgroud)

如果我包含详细输出-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]
Run Code Online (Sandbox Code Playgroud)

我们可以在这里看到Child类被加载到JVM中.

有人可以解释为什么Child不执行类中的静态块吗?

Era*_*ran 11

您看到Child该类已加载,但未初始化.

访问Child.age不会导致Child类的初始化,因为它ageParent类的成员.因此,只有Parent类被初始化,并age保持不变0.

12.4.1.发生初始化时

类或接口类型T将在第一次出现以下任何一个之前立即初始化:

  • T是一个类,并且创建了T的实例.

  • 调用由T声明的静态方法.

  • 分配由T声明的静态字段.

  • 使用由T声明的静态字段,该字段不是常量变量(第4.12.4节).

  • T是顶级类(第7.6节),并且执行在词典内嵌套在T(第8.1.3节)内的断言语句(第14.10节).

在您的情况下,您访问了声明的静态字段Parent,因此仅Parent初始化.