2010-02-18 88 views
2

我想我明白這一點,但顯然不是...泛型,方法簽名,分配

我有像這樣的方法簽名:

void doSomething(List<TypeA> typeAs){...}

List<TypeA<TypeB>> getTypeBTypeAs(){...}

但如果我嘗試並致電

doSomething(getTypeBTypeAs());

我得到一個編譯錯誤:「在類型的方法DoSomething的(名單)...是不是適用於參數(名單>)」

但是如果我改變doSomething的SIG以

void doSomething(List<TypeA<?>> typeAs){...}

它仍然無法正常工作,但

void doSomething(List typeAs){...}

顯然它的工作原理,因爲我繞過泛型。

這似乎很奇怪。

可有人能幫我嗎?

而且,在這種情況下,我想doSomething包含任何泛型類型的TypeAs任何名單的工作;未定義的TypeB,TypeC等

感謝。

回答

4

泛型類TypeA<TypeB>是從TypeA不同的類型。你不能在TypeA<TypeB>類型的參數,其中方法需要TypeA通過。另外TypeA<TypeB>TypeA<TypeC>是不同的類型,所以應用相同的約束條件。

典型的例子(從Effective Java, 2nd Ed. AFAIR)是:我們有動物(Container<Animal>)容器和作爲Animal子類,我們有LionButterfly。現在,如果你有一個方法

void func(Animal animal); 

它會接受獅子和蝴蝶。但是,此功能

void func(Container<Animal> animalContainer); 

不會接受Container<Lion>,既不是Container<Butterfly>。要意識到一個用於保護獅子安全的強大籠子不會阻止蝴蝶飛走,反之亦然,厚厚而輕盈的網狀物讓蝴蝶無法抵擋獅子。

如果你真的相信,任何一種動物的容器適合你,聲明你的函數是這樣的:

void func(Container<? extends Animal> animalContainer); 

返回到你的情況,我想唯一的方法,同時接受List<TypeA>List<TypeA<TypeB>>會是這樣像這樣:

void doSomething(List<?> list); 
+0

如果Effective Java有一個泛型例子,它必須在第二版中,因爲我的第一版坐在我的桌面上,比Java 5早幾年。 – Powerlord 2010-02-18 21:42:52

+0

是的,它在第二版中。它可以在線,谷歌它(有效的Java泛型) – Bozho 2010-02-18 21:44:11

+0

另外,如果你確實想要第二個func接受一個包含任何動物的Container,它將是'void func(Container <?extends Animal> animalContainer);'它會不會? – Powerlord 2010-02-18 21:44:51

0

試試這個:

<T> void doSomething(List<TypeA<T>> typeAs) { ... } 

請注意線路開始處的<T>。這樣doSomething接受包含任何TypeA的每個列表。

+0

不,它不會允許只是'列表' – pstanton 2010-02-18 22:16:15

+0

你是對的,現在我明白你的意思是「未定義」。 – stmax 2010-02-23 17:03:33