它是:
add(i.toArray(new Animal[i.size()]))
List.toArray返回Object[]
,无论在列表中的参数的类型:即使你可能写new List<String>().toArray()
,你会得到一个Object[]
。但是,version of toArray that takes an array to fill会返回一个正确类型的数组:如果您编写了new List<String>().toArray(new String[0])
,您将得到一个String[]
。请注意,您传入的数组的大小甚至不必与列表的大小相匹配,尽管确保它的确很好。
这最终是由于泛型的一个轻度棘手的功能。乍一看,你可能会认为String[]
和List<String>
对于它们的基本类型意味着类似的东西 - 一个是字符串数组,另一个是字符串列表。
然而,他们其实是非常不同的。
数组是一种语言原语,并且它的类型已经烘焙到其中。如果您使用了十六进制编辑器并在JVM的内存中查看了一个数组实例,那么您将能够找到(位于附近的某个地方)所保存对象类型的记录。这意味着如果你拿一个未知组件类型的数组的实例,你可以使用find out what that type is。相反,这意味着如果你打算去create an instance of an array,你需要知道你想要什么组件类型。
的List
,在另一方面,使用泛型,这在Java中与type erasure实施,这意味着,粗略地讲,它是什么,存在于编译器,而不是在运行时(编译器可以检查你做对了,但JVM不能)。这导致了一个简单而有效的实现(一个足够简单的已经被添加到pre-generics Java而无需更改JVM),但它有一些缺点 - 特别是在运行时,无法告诉类型参数在泛型类的任何特定实例上,因为类型参数只存在于编译器中。由于List
实例需要处理toArray()
,因此它唯一能做的就是创建一个Object[]
。它只是不知道使用更具体的类型。看这个
的一种方法是,数组有一个类型参数作为自己类的一部分,而List
■找一个类型参数作为自己类型的一部分,因为对象有类,但变量具有类型,您不能从一个对象中获取List
的类型实参,只能从保存对象的变量中获得(另外,您也不能从包含数组的变量中获取数组的类型实参(考虑Object[] array = new String[0];
),但这并不重要,因为变量可以让你获得一个对象 - 除非它为空)。
熬下来代码,问题是:
public <E> E[] createSimilarlyTypedArray(List<E> list) {
Class<E> componentType = list.???; // there is no way to do this
return Arrays.newInstance(componentType, list.size());
}
我不明白这个问题。你创建了自己的方法'add(Animal ...)',但是你调用ArrayList.add(Object)而不是你自己的方法。这是为什么?请使用代码的上下文编辑问题。你的'add'方法中的代码块是什么?如果你唯一的问题是你不能将Object []转换为Animal [],那么按照@Tom的回答。 – aalku
只是对将来的说明:如果您有编译器错误,请复制完整的错误消息以及与此消息相关的源代码行。 –