2009-06-27 57 views
1

我有一段代碼,我認爲應該編譯,但它沒有。下面是代碼:將具體的EnumMap對象列表傳遞給泛型EnumMap參數列表導致編譯錯誤

public class Program { 
public void myMethod(List<EnumMap<? extends MyInterface, String>> map) 
{ 

} 

public void caller() 
{ 
    EnumMap<MyEnum, String> map = new EnumMap<MyEnum, String>(MyEnum.class); 

    List<EnumMap<MyEnum, String>> list = new LinkedList<EnumMap<MyEnum, String>>(); 

    myMethod(list); //error argument type is not compatible 

} 

}

MyEnum是實現MyInterface的枚舉。

爲什麼調用myMethod(list)給我的參數類型不兼容?

如果我改變myMethod的的簽名:

public void myMethod(List<? extends Map<? extends MyInterface, String>> map) 

然後一切工作正常,但我仍然困惑,並希望知道爲什麼原來 方法簽名不起作用。

回答

1

EnumMap<MyEnum, String>EnumMap<? extends MyInterface, String>是不同的類型(前者是後者的子類型)。所以List<EnumMap<MyEnum, String>>List<EnumMap<? extends MyInterface, String>>不相互兼容。通常,如果A和B是不同的類型,則不能將List<A>分配給List<B>,而不管A和B之間的關係是什麼(同樣適用於任何泛型而不僅僅是List)。當你有一個有界的類型參數時,這是一個不同的故事;兼容性考慮了界限。

2

因此,鑑於

enum MyEnum implements MyInterface { ...} 
... 
List<EnumMap<MyEnum, String>> as = new ArrayList<EnumMap<MyEnum, String>>(); 
List<EnumMap<? extends MyInterface, String>> bs; 

我們應該能夠分配bs = as

現在假設

enum OtherEnum implements MyInterface { XXX } 
... 
EnumMap<OtherEnum, String> otherMap = 
    new EnumMap<OtherEnum, String>(OtehrEnum.class); 
otherMap.put(OtherEnum.XXX, ""); 
bs.set(0, otherMap); 
EnumMap<MyEnum, String> myMap = as.get(0); 
MyEnum xxx = myMap.keys().iterator().next(); 

otherMapmyMap指向同一個對象,但明顯不同的類型。更糟的是,xxx是tyoe MyEnum,但指向OtherEnum類型的對象。

存在多態性時指向指針的指針很困難。

+0

謝謝,我明白你在說什麼,但如何將方法簽名更改爲public void myMethod(List <?extends Map <?extends MyInterface,String >> map)使錯誤消失?錯誤不應該留下來嗎? – Alvin 2009-06-28 00:36:31

相關問題