关于不可变类防御性复制

Cra*_*ava 3 java immutability defensive-copy

我有一个关于创建Immutable类的查询.以下是我考虑的要点:

  1. 让课程最终
  2. 使所有成员最终,在静态块或构造函数中显式设置它们
  3. 让所有成员都私密
  4. 没有修改状态的方法
  5. 要非常小心地限制对可变成员组件的访问(请记住该字段可能是最终的,但对象仍然可以是可变的.即私有最终日期imStillMutable) - 请参阅防御性复制或其表兄复制构造函数以获取更多信息.


但是我根本不完全理解这一点,你能告诉或给我一个例子,其中5点在这个例子中是清楚的吗?

Jon*_*eet 5

第5点建议,任何时候你有任何方法可以返回与可变对象有关的东西,你想要创建一个独立于私有状态的副本.例如:

public final class Foo
{
    private final List<String> strings;

    public Foo(List<String> strings)
    {
        // Defensive copy on construction. Protects from constructing
        // code mutating the list.
        this.strings = new ArrayList<String>(strings);
    }

    public List<String> getStrings()
    {
        // Defensive copy on read. Protects from clients mutating the list.
        return new ArrayList<String>(strings);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,只有在状态可变时才需要防御性复制.例如,如果你使用的ImmutableList(如番石榴),如上面的类的状态,你需要创建一个建设新的列表(除非输入也是ImmutableList),但不是getStrings.

另请注意,在这种情况下String是不可变的,因此我们不需要复制每个字符串.如果这是一个List<StringBuilder>我们需要创建一个新列表和每个元素的新副本作为防御副本的一部分.正如你所看到的,当你所有的状态也是不可变的时候,生活变得更加简单.