3

假设您有一个具有 ArrayList 属性的域类。为这种类型的实例编写 getter 和 setter 时的最佳实践是什么(以避免它被修改)?

4

8 回答 8

6
public List getList() {
  return Collections.unmodifiableList(list);
}
于 2011-01-19T16:02:53.213 回答
2

Collection.unmodifiableList()使用以下方法返回一个不可修改的列表:

集合 - Collection.unmodifiableList()

于 2011-01-19T16:01:44.087 回答
1

lweller 的回应是我在大多数情况下会做的,但它确实抛出了一个UnsupportOperationException你可能不想处理的问题。在这种情况下,您可能需要考虑声明一个复合类,例如UnmodifiableList,它包含List您选择的 a 并公开您想要支持的所有方法,不包括那些会修改列表的方法。当然,这将不再与Collection接口类型兼容。

于 2011-01-19T16:16:12.380 回答
1

还可以考虑制作列表的不可变快照。

public List getList() {
    ArrayList copy = new ArrayList(this.list);
    return Collections.unmodifiableList(copy);
}
于 2011-01-19T17:14:42.460 回答
1

使用番石榴ImmutableList 类。然后,您的吸气剂应遵循以下形式:

public ImmutableList<T> getMyList() {
  ImmutableList.copyOf(myList);
}

guava 相对于 Collections.unmodifiableList 的优势在于,它向客户端显示您的集合在方法签名中是不可变的,因此人们错误地尝试向集合中添加内容的可能性很小。

于 2011-01-19T18:25:36.707 回答
1

我们有一个命名约定

listXXX(); 

给你一个只读列表。除了具有适当访问修饰符的设置器/获取器之外,可能还有设置器/获取器。

于 2011-01-19T17:39:51.103 回答
1

您可以使用Collections.unmodifiableList()。其他主要集合类型也有等价物。

于 2011-01-19T16:04:22.457 回答
1

最好的做法可能是将在列表上运行的代码移动到域类中。可能添加以适合域的方式表示序列的域类。

如果您迫切希望公开列表,那么有一个选择:

return Collections.unmodifiableList(new ArrayList<Thing>(things));
    // Bit big - shame there isn't a single method and class to do this.

return new ArrayList<Thing>(things);
    // Do you really want to see client code modifying the list?

return Collections.unmodifiableList(things);
    // Client may expecting a snapshot, modifications to the original will mess up.

请注意,如果列表的元素是可变的,您可能也想对它们做一些事情。

于 2011-01-19T17:09:49.590 回答