java - 是什么保证从另一个类的静态 block 调用静态方法按预期工作?

标签 java static jvm static-methods static-block

A 类包含:

  • 静态字符串
  • 一个静态Map,填充在类的静态 阻止
  • 一个静态方法,比如 getStr(),它返回一个从静态构建的 String 字符串

B 类包含:

  • 静态 map
  • 使用 A.getStr()
  • 填充 Map 的静态 block

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

最佳答案

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

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

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


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

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

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

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

关于java - 是什么保证从另一个类的静态 block 调用静态方法按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32876204/

相关文章:

c# - 在静态类中保存对记录器的引用

java - 强制隐式数组边界检查的最便宜方法

java.awt.headless 问题

java - TYPE_SCROLL_SENSITIVE 和 TYPE_FORWARD_ONLY 的区别

java - 查找整数中数字的值(以十六进制定义)

c - 两个静态变量的相同内存位置分配

java - 带有 this.getClass().newInstance() 的通用 main 方法

java - 如何在内存级别通过类的成员函数访问类的私有(private)成员?

xamarin - Monodroid java库绑定(bind): How to set all constructors public

java - 独立的 Java Glasshfish 客户端。引用 gf-client.jar