2011-08-02 37 views
0

如何聲明mixedList與這種快照的泛型而不修改其餘的代碼?快速遺留給泛型轉換問題

List mixedList = new ArrayList(); 
if(flagA) { 
    ClassA a = new ClassA(); //comes from elsewhere 
    mixedList.add(a) 
} else { 
    List<ClassB> bList = new ArrayList<ClassB>(); //comes from elsewhere 
    mixedList = bList; //error 
} 

我可以這樣做:

List<Object> mixedList = new ArrayList<Object>(); 
if(flagA) { 
    ... 
} else { 
    ... 
    mixedList.addAll(bList); 
} 

但有沒有辦法避免變化的代碼?

+0

我不確定你的意思,如果你將它聲明爲Object,爲什麼你需要更改其餘的代碼? –

+0

@Oscar:因爲'bList'不能分配給'mixedList'。 –

+0

很抱歉標記了線路錯誤。 – serg

回答

3

bListList<ClassB>)指定爲mixedListList<Object>)並不安全。

您從中獲得的服務bList可能會保留對其的引用;此服務將假定其列表僅包含ClassB實例。如果允許將該列表分配給List<Object>引用,那麼可以將任何類型的對象添加到列表中而不會發出警告。但是當服務,認爲列表中的每個元素都是ClassB,試圖訪問這些元素時,將會引發一個ClassCastException

創建一個新的List<Object>,並添加元素與它add()addAll(),防止這種「類型污染」。您可以安全地修改該列表的副本,並讓列表來源保留自己的副本「純」。

-1

很難知道你在問什麼,特別是關於「不改變代碼」的部分(爲什麼要問一個問題)。不過,似乎可以給予一定的邊界,以類爲您的列表:

List<? extends Class<?>> mixedList = new ArrayList<Class<?>>(); 
List<Class<String>> bList = new ArrayList<Class<String>>(); 
bList.add(String.class); 
mixedList = bList; 

此代碼編譯(用於容易編譯檢查字符串)

+0

雖然這看起來並不像他想要的那樣;你只是將類添加到列表中,而不是這些類的對象。 –

+0

噢,我會回去編輯一下(現在很忙)。 – Bohemian

0

我不相信這是可以做到。

咆哮:

Java泛型IMO只是不值得的頭痛超越了簡單的收集使用。 我可以住在演員表。衆所周知,泛型賦予了類型安全性的飾面,但在蓋子下面還有類型的猴子修補。

/咆哮完成:

這工作,但你需要在相應塊的一個可做參考交叉混合 - 在這裏,我選擇了一個List<?>mixedList和交叉混合的情況下flagA

public static void foo(boolean flagA) { 
    List<?> mixedList = new ArrayList<Object>(); 
    if(flagA) { 
     ClassA a = new ClassA(); //comes from elsewhere 
     List<Object> mixedList2 = (List<Object>) mixedList; // mod 
     mixedList2.add(a); 
    } else { 
     List<ClassB> bList = new ArrayList<ClassB>(); //comes from elsewhere 
     mixedList = bList; 
    } 
}