只是因为参考到列表是不可变的并不意味着列表它是指是不可变的。
即使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);
}
}
(请注意,这会创建一个不可修改的列表视图。如果有人抱着原来的基准,则列表仍可以通过修改。)
用细绳这种行为可能未启用。那么这里有什么不同?
这是因为String
已经是不可变的(不可修改)正如列表是,如果你把它变成一个unmodifiableList。
比较:
String data structure | List data structure
.-------------------------+------------------------------------.
Immutable | String | Collection.unmodifiableList(...) |
-----------+-------------------------+------------------------------------|
Mutable | StringBuffer | ArrayList |
'-------------------------+------------------------------------'
AFAIK实际数组列表'Collections.unmodifiableList()'返回给定列表的不可变WRAPPER。如果我是正确的,上面不会保证不变性。一个类可以实例化一个列表,实例化Example,并且仍然可以通过修改传递给构造函数的原始列表来修改Example所持有的列表。虽然答案可能足以解决分歧,但它可能无法满足严格的“不变性”要求。 – Maurice 2015-06-19 00:09:06
这是正确的。答案已更新。你可以做'Collections.unmodifiableList(new ArrayList <>(listArg))'以确保没有人持有对潜在可变列表的引用,从而避免可变性。 – aioobe 2015-06-19 07:26:41