是什么保证从另一个 class 的静态块调用静态方法按预期工作?

What guarantees that this call to a static method from another class's static block works as expected?

Class A 包含:

Class B 包含:

B的静态块总是会成功填充它的地图吗?我假设 JVM 能够处理这个问题。加载 classes 时静态块的执行顺序是否存在任何问题,进而无法保证 B 正确填充地图?我想确定一下,也许可以了解这背后的机制。

如果两个 classes 在静态初始化期间有循环依赖,事情就会变得棘手。 Java 确实有一个严格定义的初始化程序,并在检测到递归时退出。然而,这将取决于在运行时首先触发哪个 class 初始化。这意味着部分初始化的 class 可能是可见的(在您的情况下,看到空 getStr)。

循环依赖不仅令人困惑,如果两个 classes 从两个不同的线程初始化,它甚至可能导致死锁。因此,应该不惜一切代价避免它。两方之间的循环依赖总是可以通过引入第 3 方来解决。

没有循环依赖,class总是被完全初始化;在您的情况下,当 B 调用 A.getStr() 时,一定是 A 已完全初始化,并且 getStr() returns 所需的值。


作为循环依赖的例子,假设class A extends B

如果B先初始化(例如有人调用B.something),没有问题; B在初始化的过程中,遇到A.getStr,就会触发A的初始化;完成后,A.getStr 将被执行,并看到一个正确初始化的字段。

但是,如果A先初始化,就会有麻烦;会触发superclass B的初始化;当 B 调用 A.getStr 时,VM 看到 A 已经在初始化过程中,因此它会退出,不会尝试完成 A 的初始化; A.getStr 只会看到 null

为了打破这个循环,我们可以将A中B依赖的东西移动到A'。 A 和 B 都将依赖于 A'。