Java 语言规范在17.5 节中定义了 final 字段的语义:
final 字段的使用模型很简单。在该对象的构造函数中设置对象的最终字段。在对象的构造函数完成之前,不要在另一个线程可以看到它的地方写对正在构造的对象的引用。如果遵循这一点,那么当另一个线程看到该对象时,该线程将始终看到该对象的最终字段的正确构造版本。它还将看到至少与最终字段一样最新的最终字段引用的任何对象或数组的版本。
我的问题是——“最新”保证是否扩展到嵌套数组和嵌套对象的内容?
简而言之:如果一个线程将可变对象图分配给对象中的 final 字段,并且对象图永远不会更新,那么所有线程都可以通过 final 字段安全地读取该对象图吗?
一个示例场景:
- 线程 A 构造 ArrayLists 的 HashMap,然后将 HashMap 分配给类“MyClass”实例中的最终字段“myFinal”
- 线程 B 看到对 MyClass 实例的(非同步)引用并读取“myFinal”,并访问并读取其中一个 ArrayLists 的内容
在这种情况下,线程 B 看到的 ArrayList 的成员是否保证至少与 MyClass 的构造函数完成时一样最新?
我正在寻找对 Java 内存模型和语言规范语义的澄清,而不是像同步这样的替代解决方案。我梦寐以求的答案是肯定或否定,并参考相关文本。
更新:
- 我对 Java 1.5 及更高版本的语义感兴趣,即通过 JSR 133 引入的更新的 Java 内存模型。此更新中引入了对最终字段的“最新”保证。