我有一类具有各种成员变量的类。有一个构造函数,有getter方法,但没有setter方法。实际上,该对象应该是不变的。
public class Example { private ArrayList<String> list; }
现在我注意到了以下几点:当我使用getter方法获得变量列表时,可以添加新值,依此类推- 可以更改ArrayList。下次调用get()此变量时,将ArrayList返回更改的内容。怎么会这样?我没有再设置它,我只是在做它!使用String这种行为是不可能的。那么这里有什么区别?
ArrayList
get()
String
仅仅因为 对 列表 的引用 是不可变的,并不意味着 它所引用 的列表是不可变的。
即使这样list做final了也可以
list
final
// changing the object which list refers to example.getList().add("stuff");
但这 不是 允许的:
// changing list example.list = new ArrayList<String>(); // assuming list is public
为了使列表不可变(也防止第一行),建议您使用Collections.unmodifiableList:
Collections.unmodifiableList
public class Example { final private ArrayList<String> list; Example(ArrayList<String> listArg) { list = Collections.unmodifiableList(listArg); } }
(请注意,这将创建列表的不可修改视图。如果有人坚持使用原始参考,则仍可以通过该列表来修改列表。)
使用字符串,此行为是不可能的。 那么这里有什么区别?
这是因为a String已经是不可变的(无法修改),就像将列表变成unmodifiableList一样。
比较:
String data structure | List data structure .-------------------------+------------------------------------. Immutable | String | Collection.unmodifiableList(...) | -----------+-------------------------+------------------------------------| Mutable | StringBuffer | ArrayList | '-------------------------+------------------------------------'