繁体   English   中英

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

[英]Immutable objects and unmodifiable collections

对于不可变对象,将包含的集合包装为不可修改的位置在哪里合适? 我看到3个选项:

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

     public class ImmutableFactory { public Immutable build(){ List<Integer> values = new ArrayList<Integer>(); values.add(1); values.add(2); values.add(3); return new Immutable(Collections.unmodifiableList(values), "hello"); } } 
  2. 在不变的建设者中

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

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

还有其他选择,哪一个是合适的?

我想说的是,如果您创建Immutable集合,那么您需要保护自己免受某些人修改,该名单是作为构造函数的参数提供的,您应该保护性地复制它。

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

我个人很久以前就切换到Guava集合,因为在那里您可以找到不可变集合的接口。 您的构造函数如下所示:

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

您将确保收到的论据不会被任何人修改。

在不可变类中保留对不可变列表的引用通常是一个好主意,因为这样可以保证您不会错误地对其进行修改。

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

首先,您的代码在所有地方的确是不可变的, 但这仅仅是因为Integer是不可变的。
如果您拥有private final List<SomeCustomClass> values; 相反, Collections.unmodifiableList(values); 不能保证列表中的各个SomeCustomClass是不可变的。 将不得不为此编写代码。
话虽如此,另一种选择是对列表进行防御性深层复制 这种方法还提供了不变性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM