假设您有一个具有ArrayList属性的域类。为这种类型的实例编写getter和setter时最好的做法是什么(避免被修改)?
答案 0 :(得分:6)
public List getList() {
return Collections.unmodifiableList(list);
}
答案 1 :(得分:2)
使用Collection.unmodifiableList()
方法返回无法修改的列表:
答案 2 :(得分:1)
您可以使用Collections.unmodifiableList()。其他主要集合类型也有等价物。
答案 3 :(得分:1)
lweller的回答是我在大多数情况下会做的,但它会抛出你可能不想处理的UnsupportOperationException
。在这种情况下,您可能需要考虑声明一个复合类,如UnmodifiableList
,其中包含您选择的List
,并公开您要支持的所有方法,不包括那些会修改列表的方法。这个问题不再与Collection
接口类型兼容。
答案 4 :(得分: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.
请注意,如果列表中的元素是可变的,您可能也想对它们做些什么。
答案 5 :(得分:1)
还要考虑制作列表的不可变快照。
public List getList() {
ArrayList copy = new ArrayList(this.list);
return Collections.unmodifiableList(copy);
}
答案 6 :(得分:1)
我们有一个命名惯例
listXXX();
为您提供只读列表。 除了使用适当的访问修饰符之外,可能还有setter / getter。
答案 7 :(得分:1)
使用guava ImmutableList类。然后你的吸气者应该遵循以下表格:
public ImmutableList<T> getMyList() {
ImmutableList.copyOf(myList);
}
guava优于Collections.unmodifiableList的优势在于它向客户端显示您的colllection在方法签名中是不可变的,因此人们错误地尝试向集合中添加内容的可能性很小。