由于通过例如List.of(…)
或List.copyOf(…)
创建的集合不反映对指定数组或集合的后续更改,并且通常是不可变的,因此不可能在构造后执行修改,并且在没有并发修改的情况下,不可能存在任何线程安全问题.
剩下的问题是,这些藏品的建设本身是否不受不安全出版的影响.通常,您应该使用适当的 struct 将对象发布到其他线程,而不是依赖不安全的发布.
但回想一下,Unmodifiable Lists人说
- 他们都是unmodifiable岁.不能添加、删除或替换元素.调用列表上的任何赋值函数方法都会导致抛出
UnsupportedOperationException
.但是,如果包含的元素本身是可变的,这可能会导致列表的内容似乎发生变化.…
- 他们都是value-based岁.
沿着value-based的链接,我们发现:
基于值的类
有些类(如
java.lang.Integer
和java.time.LocalDate
)是基于值的.基于值的类具有以下属性:
- 该类仅声明最终实例字段(尽管这些字段可能包含对可变对象的引用);
…
对于不受不安全发布影响的不可变对象,最终字段非常重要.AS JLS§17.5. final
Field Semantics指定:
final
字段还允许程序员在没有同步的情况下实现线程安全的不可变对象.线程安全的不可变对象被所有线程视为不可变,即使使用数据争用来在线程之间传递对不可变对象的引用.这可以提供安全保证,防止不正确或恶意代码误用不可变的类.
但我们仍然必须假设JDK开发人员的意图是"实现线程安全的不可变对象",而不是通过显式使用final
个字段来让开发人员感到惊讶,然后故意 destruct 安全保证.
如果有疑问,请使用安全出版物.不会疼的.
即使您已经说过这一点,但需要强调的是,如果所包含的元素是可变的,则这并不适用于它们.