为什么 java 不与静态外部字段同时初始化静态嵌套 class 字段?

Why does java not initialise static nested class fields at the same time as static outter fields?

Java 在与 class 交互时初始化外部 class 静态字段,但不初始化嵌套静态 class 字段。

所以我已经阅读了嵌套的 class 文档:https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html 我认为它归结为这里的这一行:

In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

如果我的理解是正确的,那意味着 java 将我下面的两个 class 视为单独的实体;

public class OutterClass {

    private static final OutterClass outterField = new OutterClass("outterField");

    private OutterClass(String string) {
        System.out.println(string + " has been initialised");
    }

    private static class InnerClass {
        private static final OutterClass innerField = new OutterClass("innerField");
    }

    public static void foo() {}
}

意味着当我通过调用 Outer.foo()OuterClass 交互时,java 将初始化我的静态字段,因为它是 OuterClass 的一部分。但由于它将 InnerClass 视为单独的顶层 class,因此 InnerClass 的字段不会被初始化。

1)我的理解正确吗?

2) 这与 JIT 编译器或 class 加载器有什么关系吗?加载OuterClass时是否加载了InnerClass

谢谢

1) Is my understanding correct?

基本上是的。想想你的 static 成员 outerField 会发生什么:

public class OutterClass {

    private static final OutterClass outterField = new OutterClass("outterField");

理论上,JVM 可能会在程序启动 运行 或加载 class 时创建 static final 对象,但事实并非如此。相反,它只会在需要时初始化它 - 基本上:

  • class 的实例已创建,或
  • 访问了 Class 的静态字段或方法之一

(参见 https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

静态内部也是如此class。正如您所说,JVM 将其视为顶级内部 class,因此只会在需要时才初始化其成员。

2) Has this got anything to do with the JIT compiler or the class loader?

没有也没有。静态成员的初始化不会在 class 加载时发生,而是稍后发生(正如我们所说,当 class 被访问时)。这不是编译器优化的问题,而是明确指定的行为。毕竟,当您加载一个可能很大的 class 库时,您不希望您的 JVM 消耗内存或花时间初始化您的程序从未接触过的 classes 的所有静态成员;仅按需是一种更好的方法。

Is the InnerClass loaded when the OuterClass is loaded?

是(但当时没有初始化)