假设您有一个具有 ArrayList 属性的域类。为这种类型的实例编写 getter 和 setter 时的最佳实践是什么(以避免它被修改)?
8 回答
public List getList() {
return Collections.unmodifiableList(list);
}
Collection.unmodifiableList()
使用以下方法返回一个不可修改的列表:
lweller 的回应是我在大多数情况下会做的,但它确实抛出了一个UnsupportOperationException
你可能不想处理的问题。在这种情况下,您可能需要考虑声明一个复合类,例如UnmodifiableList
,它包含List
您选择的 a 并公开您想要支持的所有方法,不包括那些会修改列表的方法。当然,这将不再与Collection
接口类型兼容。
还可以考虑制作列表的不可变快照。
public List getList() {
ArrayList copy = new ArrayList(this.list);
return Collections.unmodifiableList(copy);
}
使用番石榴ImmutableList 类。然后,您的吸气剂应遵循以下形式:
public ImmutableList<T> getMyList() {
ImmutableList.copyOf(myList);
}
guava 相对于 Collections.unmodifiableList 的优势在于,它向客户端显示您的集合在方法签名中是不可变的,因此人们错误地尝试向集合中添加内容的可能性很小。
我们有一个命名约定
listXXX();
给你一个只读列表。除了具有适当访问修饰符的设置器/获取器之外,可能还有设置器/获取器。
您可以使用Collections.unmodifiableList()。其他主要集合类型也有等价物。
最好的做法可能是将在列表上运行的代码移动到域类中。可能添加以适合域的方式表示序列的域类。
如果您迫切希望公开列表,那么有一个选择:
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.
请注意,如果列表的元素是可变的,您可能也想对它们做一些事情。