不可变对象和不可修改的集合

使用不可变对象,将包含的集合包装为不可修改的位置是正确的? 我看到3个选项:

  1. 在不可变对象的工厂中:

    public class ImmutableFactory { public Immutable build(){ List values = new ArrayList(); values.add(1); values.add(2); values.add(3); return new Immutable(Collections.unmodifiableList(values), "hello"); } } 
  2. 在immutable的构造函数中

     public class Immutable { private final List values; private final String hello; public Immutable(List values, String hello) { this.values = Collections.unmodifiableList(values); this.hello = hello; } public List getValues() { return values; } public String getHello() { return hello; } } 
  3. 在immutable的访问器中(如果适用)。

     public class Immutable { private final List values; private final String hello; public Immutable(List values, String hello) { this.values = values; this.hello = hello; } public List getValues() { return Collections.unmodifiableList(values); } public String getHello() { return hello; } } 

有没有其他选择,哪一个是正确的?

我会说如果你创建了Immutable集合,那么你需要保护自己免受某人修改作为构造函数的参数给出的列表,你应该保护性地复制它。

 public Immutable(List values, String hello) { this.values = Collections.unmodifiableList(new ArrayList(values)); this.hello = hello; } 

我个人很久以前就切换到了Guava集合,因为在那里你可以找到不可变集合的接口。 你的构造函数看起来像这样:

 public Immutable(ImmutableList values, String hello) { this.values = values; this.hello = hello; } 

你确定你收到的论点不会被任何人修改。

在不可变类中保持对不可变列表的引用通常是个好主意,因为它确保您不会错误地修改它。

我认为Case(1)只有当工厂方法是创建不可变集合的唯一方法时才有意义,即使这样,当有人重构这些类时它也可能会中断。 除非有其他限制,否则最好创建自给自足的类。

首先,您在所有地方的代码确实是不可变的, 仅仅因为Integer是不可变的。
如果你有private final List values; 相反, Collections.unmodifiableList(values); 不保证列表中的个别SomeCustomClass是不可变的。 必须为此编码。
话虽如此,另一个选择是做一个清除列表的深层副本 。 这种方法也提供了不变性。