2010-05-20 121 views
7

请帮我这个:Java的泛型集合

如果Lion IS-A Animal并给予Cage<T>

Cage<? extends Animal> c = new Cage<Lion>(); // ok, 

Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); // not ok 

我看不出这里有什么?

回答

6

使用非通配类型T分配给变量(Set<T>)时,被分配的对象必须具有T作为其通用类型(包括所有通用类型参数T,通配符和非通配符)。在你的情况下,TCage<Lion>,它与Cage<? extends Animal>不同。

你能做什么,因为Cage<Lion>是分配给Cage<? extends Animal>,是使用通配符类型:

Set<? extends Cage<? extends Animal>> a = new Set<Cage<Lion>>(); 
+0

+1为实际解决方案。 – 2010-05-20 19:50:16

+0

谢谢,对我来说,那是缺失的部分。 – 2010-05-23 17:26:53

6

这是错误的,因为如果允许,那么这将是合法的:

Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); 
cc.add(new Cage<Tiger>()); // legal -- Cage<Tiger> is a Cage<? extends Animal> 

Cage<Tiger>是宣言的范围内,但没有定义,所以这会崩溃。

+0

如何Java的决定是否申请逆变/协方差或不? – Simon 2010-05-20 18:21:48

+0

我的理解Java将泛型视为不变(但奇怪的是,将数组视为协变和类型检查在运行时),但通过使用合适的通配符(适当扩展或超级)参数编写方法,以及一些铸造和抑制未检查的转换,你可以给你一个合适的印象。 – pdbartlett 2010-05-20 18:33:44

2

您需要:

Set<? extends List<? extends Number>> cc = new HashSet<ArrayList<Integer>>(); 

要解释为什么...我想备份到一个简单的版本的例子:

Number a = new Integer(1); // OK 
Set<Number> b = new HashSet<Integer>(); // not OK 

这不起作用,因为它将使

b.add(new Double(3.0));