2009-09-25 92 views
8

对不起,如果标题看起来很混乱,但有些例子是按顺序的。为什么不能将包含泛型类型的泛型类型分配给泛型类型的泛型类型

比方说,我有一些Java类与泛型类型参数:

public class GenericClass<T> { 
} 

我可以创建类型的存储对象,设置为通用参数变量,说String。 Java也会让我该变量赋值给另一个变量,但与设置为通配符<?>类型的泛型参数:与通用参数类时

GenericClass<String> stringy = ... 
GenericClass<?> generic = stringy; // OK 

但是,如果设置该参数的类型是通用,则不能然后那个类的一个对象分配给相同类型/泛型化类型,其中后者(内/嵌套)参数是通配符类型<?>的:

GenericClass<GenericClass<String>> stringy = ... 
GenericClass<GenericClass<?>> generic = stringy; // Compile Error 

// And just in case that is confusing, a more 
// realistic example involving Collections: 
List<GenericClass<String>> stringy = ... 
List<GenericClass<?>> generic = stringy; // Compile Error 

特定编译错误是:

Type mismatch: cannot convert from List<GenericClass<String>> to List<GenericClass<?>> 

直觉上我会认为这个任务不应该是个问题。那么为什么这个任务是一个问题?

+0

http://stackoverflow.com/questions/1341093/nested-generics-with-wildcards的副本 – Dirk 2009-09-25 10:29:19

回答

8

你面对计价Covariance问题。

List<GenericClass<String>> stringy = ... 
List<GenericClass<?>> generic = stringy; 
generic.add(new GenericClass<Integer>()); 

如果这不是编译错误,那么代码的最后一行是可能的。

你可以让周围的错误做这个:

List<? extends GenericClass<?>> generic = stringy; 

,但你不能使用add也因为你真的不知道? extends GenericClass<?>是(协方差再次)什么。在这种情况下,您只能通过列表进行枚举并期望GenericClass<?>

4

从技术上讲,这是因为List<GenericClass<String>>不是List<GenericClass<?>>的子类型。为了使其工作,你可以不喜欢

List<? extends GenericClass<?>> generic = stringy 

应该达到预期效果(虽然是很丑陋......)。

见,例如,this SO question更多细节