不可变类的策略 - 这是一个矛盾吗?

时间:2017-08-06 13:00:22

标签: java immutability

strategy for defining an immutable class包含2个点:

  1. 将该字段标记为私有和最终
  2. 不提供制定者
  3. 我的困惑之处在于:当我将字段标记为private final时,省略setter的额外安全性会给出什么?

    由于该字段是私有的,因此如果没有类方法,则无法在类外访问它。但由于它也是最终的,因此在初始化后无法修改。

    假设在下面的类中,如果我没有在突出显示的2个位置初始化我的字段,那么编译器会给出错误,即最终空白字段尚未初始化,这意味着将该字段标记为final,won&# 39; t让我构造一个对象而不初始化最终字段,这意味着在创建对象后只存在这样一个字段的1个值

    class MyImmutable {
      private final int field1; // either initialze here
    
      MyImmutable() {
         this.field1 = ... ; // or here
      }
    }
    

1 个答案:

答案 0 :(得分:3)

不。本文只是明确了不可变类型的属性。

他们引用了“#34; setter"然后精确定义。确切的引用声明:

  

不要提供" setter"方法 - 修改字段引用的字段或对象的方法

private final并不总能确保不变性。在您的示例中,private final就足够了,因为field1是基本类型。

仔细看看引用:

  

修改字段的方法或字段引用的对象

如果MyImmutable由可变类型组成,则设置者可以委托对它们进行调用,从而导致MyImmutable发生变异,无论MyImmutable中的字段是否已标记为private final或不。

以下是使用private final的示例,但该类型由可变类型组成,setter委托调用该类型:

@Immutable
class Person {
    private final Identity identity; // Identity is a mutable type

    public void changeNameTo(String name) {
        identity.changeNameTo(name); // private final can't prevent this
    }
}

@Mutable
class Identity {
    private String name;

    public void changeNameTo(String name) {
        this.name = name;
    }
}

decomposing现有代码时,这是一种常见的策略。