【发布时间】:2017-08-06 13:00:21
【问题描述】:
strategy for defining an immutable class 包含 2 个点:
- 将该字段标记为私有和最终字段
- 不提供二传手
我的困惑是:当我将该字段标记为 private final 时,省略 setter 会带来什么额外的安全性?
由于该字段是私有的,没有类方法就不能在类外访问。但是因为也是final的,所以初始化后就不能修改了。
假设,在下面的类中,如果我没有在突出显示的 2 个地方初始化我的字段,那么编译器会给我一个错误,即最终的空白字段尚未初始化,这意味着 将文件标记为最终的,不会' t 让我在不初始化 final 字段的情况下构造一个对象,这意味着在对象创建后只会存在这样一个字段的 1 个值
class MyImmutable {
private final int field1; // either initialze here
MyImmutable() {
this.field1 = ... ; // or here
}
}
【问题讨论】:
-
你没有意识到链接的文章是一个食谱,其中第一步(不是第二步!)是“不提供“setter”方法”,然后第二步(不是第一步!)是“制作所有字段
final和private”。按照这个顺序,它比您在问题中提出的顺序更有意义。文章中列出的这四个步骤提供了一种不可变的感觉。 -
private final不能确保不变性。MyImmutable类型可以由一个可变对象组成,该对象由 setter 委托给(在分解现有代码时很常见)。只要 Setter 不改变状态,它们就很好。您的示例仅是合理的,因为它仅由原始类型组成。如果MyImmutable由可变引用类型组成,那就另当别论了。 -
@VinceEmigh 链接文章中的其他两个步骤已解决。
-
@MarkRotteveel 是的,它已通过第四步解决。但是该声明清楚地说明了它对“二传手”的定义。以下语句,例如标记字段
private final,将使第一个语句毫无意义。但这绝对是他们试图理解的重点:“这个类中有两个 setter 方法。......第二个,invert,可以通过创建一个新对象而不是修改现有对象来适应一个。" - 可以说他们用尽了相似的点,我个人会说他们对单个点(不变性)很明确。
标签: java immutability