我在我的一个Java项目类中使用了一个ArrayList。该类会跟踪列表是否已更改,并提供了一些公共方法来添加和删除列表中自动将变量设置为“已更改”的元素。
到目前为止,该列表是公开的,因为我希望我的列表可以从任何地方公开读取。但我只希望拥有该列表的类能够修改它。所以没有来自外部类的修改。那可能吗?如果是这样,怎么样?
通常对于访问控制,您可能使用getter和setter方法。但即使使用getter方法并将列表设置为private,另一个类仍然可以执行getList().remove(element)
,从而从外部修改列表,而不会注意到列表已更改。
答案 0 :(得分:2)
将您的ArrayList字段设为私有,但让您的getter返回Collections.unmodifiableList(list)
,它提供了一个不可修改的视图。
这将允许外部代码将其视为普通List,用于每个循环等,但将禁用修改操作。此外,unmodifiableList以固定时间返回视图。
这实际上是它的设计用例。的Javadoc:
此方法允许模块为用户提供对内部列表的“只读”访问权限。对返回列表的查询操作“读取”到指定列表,并尝试修改返回的列表,无论是直接还是通过其迭代器,都会导致UnsupportedOperationException。
答案 1 :(得分:1)
您可以将ArrayList
成员设为私有,而不是返回ArrayList
的getter,而是使用接受索引i
的getter并返回i
& #39; ArrayList
的元素。
public class Test
{
private List<String> list = new ArrayList<String>();
public getString (int i)
{
// you might want to add some validation of i here
return list.get(i);
}
}
getString
允许您的类用户访问列表中的任何元素,而无法对其进行修改。
如果您希望允许您的用户迭代列表而不能修改它,您可以添加getSize()
方法来返回列表的大小(这将允许用户迭代列表使用常规for循环),或者您的类可以实现Iterable
(不支持删除操作)。
答案 2 :(得分:1)
将您的列表设为私有并添加getter方法:
public List getList(){
return new ArrayList(yourPrivateList);
}
答案 3 :(得分:1)
你有几个选择:
Collections.unmodifiableList(..)
。 Check the documentation here. 答案 4 :(得分:0)
我认为您最好的选择是保持List
隐私并添加一个getter方法,该方法返回List
的副本,但不会返回List
的副本本身。例如:
public class EncapsulationTest {
private List<Object> privateList = new ArrayList<Object>();
// Your constructors and methods to track list
// modification here ...
public List<Object> getList() {
// Maybe you need a null check here
return new ArrayList<Object>(privateList);
}
public void addElement(Object newElement) {
this.privateList.add(newElement);
// Set your 'changed' variable to true
}
public void removeElement(Object element) {
this.privateList.remove(element);
// Set your 'changed' variable to true
}
}
如果您这样做,您仍然可以阅读List
的完全副本,但无法修改List
本身。实际上,您可以修改返回的List
,但由于它是一个不同的对象,因此更改不会影响对象的List
。
我希望它有所帮助。