只是因爲參考到列表是不可變的並不意味着列表它是指是不可變的。
即使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