问题描述
必须不可变对象的所有属性都是 final
?
Must immutable objects have all properties be final
?
据我所知。但我不知道,我是否是对的。
According to me not. But I don't know, whether I am right.
推荐答案
不可变对象(所有属性final)和一个有效的不可变对象(属性不是最终的但不能更改)是安全的发布。
The main difference between an immutable object (all properties final) and an effectively immutable object (properties aren't final but can't be changed) is safe publication.
您可以安全地在多线程上下文中发布不可变对象而无需由于:
You can safely publish an immutable object in a multi threaded context without having to worry about adding synchronization, thanks to the guarantees provided by the Java Memory Model for final fields:
作为旁注,它还可以强制实现不变性(如果你试图在类的未来版本中改变这些字段,因为你忘了它应该是不可变的,它不会编译)。
As a side note, it also enables to enforce immutability (if you try to mutate those fields in a future version of your class because you have forgotten it should be immutable, it won't compile).
澄清
- 使一个对象的所有字段最终都不会使它成为不可变的 - 你还需要确保(i)它的状态不能更改(例如,如果对象包含
最终列表
,则不得在构建后进行变异操作(添加,删除...)和(ii)您不要 - 一个有效不可变的对象一旦安全发布就是线程安全的 $ b $让
-
不安全发布的示例:
在构造期间转义
b - Making all the fields of an object final does not make it immutable - you also need to make sure that (i) its state can't change (for example, if the object contains a
final List
, no mutating operations (add, remove...) must be done after construction) and (ii) you don't letthis
escape during construction - An effectively immutable object is thread safe once it has been safely published
Example of unsafe publication:
class EffectivelyImmutable {
static EffectivelyImmutable unsafe;
private int i;
public EffectivelyImmutable (int i) { this.i = i; }
public int get() { return i; }
}
// in some thread
EffectivelyImmutable.unsafe = new EffectivelyImmutable(1);
//in some other thread
if (EffectivelyImmutable.unsafe != null
&& EffectivelyImmutable.unsafe.get() != 1)
System.out.println("What???");
这个程序理论上可以打印什么???
。如果 i
是最终的,那将不是合法的结果。
This program could in theory print What???
. If i
were final, that would not be a legal outcome.
这篇关于必须是不可变对象的所有属性都是最终的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!