我有一个包含各种成员变量的类。有一个构造函数,有 getter 方法,但没有 setter 方法。事实上,这个对象应该是不可变的。
public class Example {
private ArrayList<String> list;
}
现在我注意到以下情况:当我使用 getter 方法获取变量列表时,我可以添加新值等等 - 我可以更改 ArrayList
。当我下次为此变量调用 get()
时,将返回更改后的 ArrayList
。怎么会这样?我没有再设置它,我只是在努力!
使用 String
这种行为是不可能的。那么这里有什么区别呢?
最佳答案
仅仅因为对列表的引用是不可变的并不意味着它引用的列表是不可变的。
即使将 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
:
public class Example {
final private ArrayList<String> list;
Example(ArrayList<String> listArg) {
list = Collections.unmodifiableList(listArg);
}
}
(请注意,这会创建一个不可修改的 ListView 。如果有人保留原始引用,那么仍然可以通过它修改列表。)
With a String this behaviour isnt possible. So what is the difference here?
这是因为 String
已经是不可变的(不可修改的),就像您将列表变成 unmodifiableList 时一样。
比较:
String data structure | List data structure
.-------------------------+------------------------------------.
Immutable | String | Collection.unmodifiableList(...) |
-----------+-------------------------+------------------------------------|
Mutable | StringBuffer | ArrayList |
'-------------------------+------------------------------------'
关于java - 具有 ArrayList 成员变量的不可变对象(immutable对象) - 为什么可以更改此变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6137224/