2014-08-27 241 views
4

工作用一个例子解释这个问题:Java泛型:无界通配符不与对象类型参数

public class DataWrapper<T> { 
    T data; 
}; 

DataWrapper<Object> obj1 = new DataWrapper<Object>(); 

List<DataWrapper<?>> anyDataList = Arrays.asList(obj1); //this doesn't work 

DataWrapper<Integer> objInt = new DataWrapper<Integer>(); 
anyDataList = Arrays.asList(obj1, objInt); //this work 

我不明白为什么“Arrays.asList(OBJ1)”不工作?

+4

升级到Java 8获得更好的结果:) – 2014-08-27 19:36:28

+0

Java类型系统是相当困难的代码,而无需一个IDE左右,这是肯定的。 – 2014-08-27 19:39:19

+0

确认:这个解释在Java 8 – therealrootuser 2014-08-27 19:40:05

回答

9

当推断泛型方法的类型参数时,Java 7很愚蠢(并非不是)。例如,它将使用声明的参数类型来推断类型,而不管方法调用的上下文。因此,在

Arrays.asList(obj1); 

类型参数会被推断为

DataWrapper<Object> 

方法的返回类型将被List<DataWrapper<Object>>这是没有分配给一个List<DataWrapper<?>>

Arrays.asList(obj1, objInt); 

类型是从两个参数推断。两者之间有共同的类型。在这种情况下,这是? extends Object。方法返回类型变为List<DataWrapper<? extends Object>>,可指定给List<DataWrapper<?>>

在Java 8中,您发布的内容是开箱即用的。在Java 7中,可以提供一个明确的类型参数,使其工作

List<DataWrapper<?>> anyDataList = Arrays.<DataWrapper<?>>asList(obj1); 
+0

+1中有效。你还可以为使用Java 7的人提供解决方法吗? – StriplingWarrior 2014-08-27 19:43:43

+1

@StriplingWarrior Yup补充道。谢谢! – 2014-08-27 19:45:13

+0

DataWrapper 可以分配给DataWrapper 。扩展这个逻辑,我预计这个通配符还可以用于二级嵌套类型参数:List >应该可以分配给List > – user1447561 2014-08-27 19:45:58