2010-02-18 57 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