为什么下面的代码抛出这个错误:不存在类型变量的实例,因此Object确认为Number?
List<Object> source = Arrays.asList(1,2,3);
List<Number> dest = Arrays.asList(4.1,5,6,9.1);
Collections.copy(dest, source);
您可以强制转换源List
以使代码正常工作:
Collections.copy(dest, (List<Number>) (List) source);
请注意,如果source
包含非数字元素,则此代码将引发模糊异常(ArrayStoreException
(。也许您应该重新考虑将数字存储在Object
列表中。
由于Collections.copy
:的签名,无法将Object
的列表复制到Number
的列表
public static <T> void copy(List<? super T> dest, List<? extends T> src)
这两个约束基本上保证了不能直接将超类型列表复制到子类型列表。
在JDK8上,您会得到一条稍微有用的错误消息:
Main.java:14: error: method copy in class Collections cannot be applied to given types;
Collections.copy(dest, source);
^
required: List<? super T>,List<? extends T>
found: List<Number>,List<Object>
reason: inference variable T has incompatible bounds
lower bounds: Number,Object
lower bounds: Object
where T is a type-variable:
T extends Object declared in method <T>copy(List<? super T>,List<? extends T>)
如果您查看Collections.copy
:
public static <T> void copy(List<? super T> dest, List<? extends T> src) {}
您发现两个自变量都应该是List
,并且dest
在层次中应该高于src
。在您的示例中-Number <- Object
,因此您有ComplieTimeException
。
如果你喜欢这个:
Collections.copy(source, dest);
你不会有这样的错误。
这是因为dest数组中的所有元素都必须是Number
类型,但源数组中的对象不可能是这种类型,因为它们是Object
类型,可以是任何类型。
请参阅:
List<Object> source = Arrays.asList(1,2,3,"string allowed here");
List<Number> dest = Arrays.asList(4.1,5,6,9.1);
Collections.copy(dest, source);