The accepted Answer作者Bozho是正確的。這裏有更多信息,示例代碼和建議的替代方法。
的unmodifiableList是背靠原版
,在Collections
實用類unmodifiableList
方法不創建一個新的列表,它會創建一個假名單由原始列表支持。任何通過「不可修改」對象進行的添加或刪除嘗試都將被阻止,因此名稱將達到其目的。但事實上,正如你所顯示的那樣,原始列表可以被修改,並同時影響我們的次要的不太不可修改的列表。
這是類文檔中列明:
返回指定列表的不可修改視圖。此方法允許模塊爲用戶提供對內部列表的「只讀」訪問權限。將返回列表上的查詢操作「讀取」到指定列表中,並嘗試修改返回的列表,無論是直接還是通過其迭代器,都會導致UnsupportedOperationException。
第四個字是關鍵:view
。新的列表對象不是新鮮的列表。這是一個覆蓋。就像tracing paper或transparency film在圖紙上停止您在圖紙上標記,它不會阻止您從底層修改原始圖紙。
道德故事:不要使用Collections.unmodifiableList來製作列表的防禦副本。
同上Collections.unmodifiableMap
,Collections.unmodifiableSet
等等。
下面是演示該問題的另一個示例。
String dog = "dog";
String cat = "cat";
String bird = "bird";
List<String> originalList = new ArrayList<>(3);
originalList.add(dog);
originalList.add(cat);
originalList.add(bird);
List<String> unmodList = Collections.unmodifiableList(originalList);
System.out.println("unmod before: " + unmodList); // Yields [dog, cat, bird]
originalList.remove(cat); // Removing element from original list affects the unmodifiable list?
System.out.println("unmod after: " + unmodList); // Yields [dog, bird]
谷歌番石榴
取而代之的Collections
類,用於防禦式編程我建議使用Google Guava庫及其ImmutableCollections設施。
您可以創建一個新的列表。
public static final ImmutableList<String> ANIMALS = ImmutableList.of(
dog,
cat,
bird);
或者您可以製作現有列表的防禦副本。在這種情況下,你會得到一個新的單獨列表。從原始列表中刪除而不是會影響(縮小)不可變列表。
ImmutableList<String> ANIMALS = ImmutableList.copyOf(originalList); // defensive copy!
但要記住,而收集的自己的定義是不同的,所包含的對象由最初的名單和新的不可變列表都共享。在製作防禦性副本時,我們不會重複「狗」對象。只有一個狗對象留在內存中,這兩個列表都包含指向同一只狗的引用。如果「狗」對象中的屬性被修改,兩個集合都指向同一個單獨的狗對象,因此兩個集合都會看到狗的新屬性值。
什麼你正在尋找被稱爲「不可變列表。」番石榴有這個。 (http://guava-libraries.googlecode.com) – 2010-09-09 14:02:33
Google Guava,[ImmutableCollections](https://github.com/google/guava/wiki/ImmutableCollectionsExplained)< - 更新了doc鏈接。 – 2015-09-02 21:53:35