當我深入探索ImmutableList
的gs-collection源時,它不會延伸java.util.List
。然而,javadoc類提到所有ImmutableList實現必須實現java.util.List
。ImmutableList不擴展List?
爲什麼要問執行java.util.List
而不是ImmutableList
本身延長java.util.List
?
當我深入探索ImmutableList
的gs-collection源時,它不會延伸java.util.List
。然而,javadoc類提到所有ImmutableList實現必須實現java.util.List
。ImmutableList不擴展List?
爲什麼要問執行java.util.List
而不是ImmutableList
本身延長java.util.List
?
爲什麼ImmutableList
延伸List
?
ImmutableCollection
不延伸java.util.Collection
(和ImmutableList
不延伸java.util.List
),因爲已經Collection
突變等add()
和remove()
方法。如果不可變的集合具有這些方法,則它們總是必須拋出UnsupportedOperationException
。對於不可變集合的用戶,將自動完成選項中的add()
和remove()
看作可調用方法會很奇怪。
爲什麼Javadoc強加一個合同,所有的ImmutableList
實現也實現List
?
歸結爲平等。 ImmutableList
應該等於List
,假定兩個列表具有相同順序的相同內容。 List.equals()
imposes a Javadoc contract其中指出:
返回true當且僅當該指定的對象也是一個列表,兩者 列表具有相同的大小,並且在 元件的所有相應對的兩個列表是相等的。
這是什麼意思,「指定的對象也是一個列表?」我們可以在AbstractList.equals()
看到它的意思是instanceof List
。
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
...
}
因此,所有ImmutableList
實現也必須實現List
爲equals()
以對稱的方式工作。不可變的集合工廠已經隱藏了實現細節,比如一個具有單個元素的不可變列表由ImmutableSingletonList
實現。它還隱藏了List
界面。
互操作
這種設計的好處是,ImmutableList
可強制轉換爲List
這是與現有的API的互操作很重要。
// Library method - cannot refactor the parameter type
public void printAll(List<?> list)
{
for (Object each : list)
{
System.out.println(each);
}
}
ImmutableList<Integer> immutableList = Lists.immutable.with(1, 2, 3);
List<Integer> castList = immutableList.castToList();
printAll(castList);
// also works
printAll((List<?>) immutableList);
// throws UnsupportedOperationException
castList.add(4);
注:我在GS Collections開發。
感謝您長時間回答,這是有道理的,但我猜這是一種設計風格。就個人而言,我寧願讓add()和remove()拋出UnsupportedOperationException,而不是調用castToList()。開發人員應該知道,如果代碼使用ImmutableList,添加和刪除將不起作用,這是開發人員的問題,而不是設計問題。但我想這只是個人意見。再次感謝您的回答 – Wins
我認爲您可能對UnmodifiableMutableList及其工廠方法MutableList.asUnmodifiable()感興趣。我保持這個答案限於ImmutableList,但隨時提出一個關於差異的新問題,我會回來寫更多。 –
我明白不可修改的可變列表(名稱是非常明確的),但我問的是爲什麼不使ImmutableList擴展列表,拋出UnsupportedOperationException添加和刪除,但保留列表和它包含的對象的不變性。 – Wins
它擴展了什麼? –
它的根,它擴展'java.lang.Iterable' – Wins
奇怪的設計。而不是把一個不可執行的要求放入Javadoc中,他們可能只寫了'extends java.util。列表「並自動執行。 – EJP