-->

对于一个不可变类防御性复制(Regarding an Immutable class defensi

2019-09-21 07:34发布

我有一个关于创建一个不可变类的查询。 以下是我拿在考虑几点:

  1. 使课堂最后
  2. 让所有成员最终,将它们明确,在静态块,或在构造函数
  3. 使所有成员私人
  4. 没有修饰状态的方法
  5. 要格外小心,以限制访问可变梁构件(记住该领域可能是最终的,但对象仍然可以是可变的,即私人最终日期imStillMutable。) - 参见防守复制或它的更多信息表妹拷贝构造函数。


但我不完全理解的5点全部,你可以请指教或告诉我一个例子,其中的5点在这个例子清楚了吗?

Answer 1:

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);
    }
}

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

另外请注意,在这种情况下, String是不变的,所以我们并不需要每个字符串复制。 如果这是一个List<StringBuilder>我们需要创建一个新的列表,每个元素的新副本的副本防守的一部分。 正如你所看到的,当你所有的状态是不可变的太的生活变得更简单。



Answer 2:

final意味着指示器不能指向的另一参考。 例如:

final Object obj = new Object();
obj = new Object(); //Invalid

final并不妨碍modifiying对象:

obj.setWhatever("aaa"); //Perfectly valid

如果你还没有限制访问的成员,那么任何人都可以获取对象并对其进行修改。

例如: yourClass.getObject().setWhatever("aaa").

防守复制是指getObject()不会直接返回对象,但它会使它的一个副本,然后返回。 如果这样,来电者修改了返回的对象,也不会修改类的创始成员。



文章来源: Regarding an Immutable class defensive copying