2015-04-08 39 views
5

當我深入探索ImmutableList的gs-collection源時,它不會延伸java.util.List。然而,javadoc類提到所有ImmutableList實現必須實現java.util.ListImmutableList不擴展List?

爲什麼要問執行java.util.List而不是ImmutableList本身延長java.util.List

+2

它擴展了什麼? –

+1

它的根,它擴展'java.lang.Iterable' – Wins

+0

奇怪的設計。而不是把一個不可執行的要求放入Javadoc中,他們可能只寫了'extends java.util。列表「並自動執行。 – EJP

回答

11

爲什麼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實現也必須實現Listequals()以對稱的方式工作。不可變的集合工廠已經隱藏了實現細節,比如一個具有單個元素的不可變列表由ImmutableSingletonList實現。它還隱藏了List界面。

ImmutableList class diagram

互操作

這種設計的好處是,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開發。

+2

感謝您長時間回答,這是有道理的,但我猜這是一種設計風格。就個人而言,我寧願讓add()和remove()拋出UnsupportedOperationException,而不是調用castToList()。開發人員應該知道,如果代碼使用ImmutableList,添加和刪除將不起作用,這是開發人員的問題,而不是設計問題。但我想這只是個人意見。再次感謝您的回答 – Wins

+2

我認爲您可能對UnmodifiableMutableList及其工廠方法MutableList.asUnmodifiable()感興趣。我保持這個答案限於ImmutableList,但隨時提出一個關於差異的新問題,我會回來寫更多。 –

+2

我明白不可修改的可變列表(名稱是非常明確的),但我問的是爲什麼不使ImmutableList擴展列表,拋出UnsupportedOperationException添加和刪除,但保留列表和它包含的對象的不變性。 – Wins