[英]Java / Generics / Array problems
我想最终了解泛型和数组之间的关系,因此我将基于ArrayList<T>
提供一个与我不一致的示例:
Object[] elementData = new Object[size];
这是通用列表元素的存储位置。
public void add(T element){ elementData[size++] = element; }
public T get(int index) { return (T)elementData[index] }
完全有效。 我可以找出底层的<T>
对象,但是包含对这些对象的引用的数组是Object
。
与此相反:
public Object[] toArray()
{
Object[] result = new Object[size];
for(int i = 0;i<size;i++)
{
result[i] = elementData[i];
}
return result;
}
我无法将返回数组中的元素强制转换为它们的真实类型,但是整个设置是相同的:一个Object
数组,其中包含对<T>
对象的引用。 尝试将元素转换为实型时出现ClassCastException
错误。
如果查看Collection
接口,则会发现有2个toArray()
方法:
Object[] toArray()
返回一个包含此集合中所有元素的数组。
<T> T[] toArray(T[] a)
返回包含此集合中所有元素的数组; 返回数组的运行时类型是指定数组的运行时类型。
这样做的原因是您无法创建通用数组,因此仅返回Object []。
为您的toArray()
创建通用方法很简单:
public <T> T[] toArray(T[] arr)
{
T[] result = arr.size == size ? arr : (T[])java.lang.reflect.Array
.newInstance(arr.getClass().getComponentType(), size);
for(int i = 0;i<size;i++)
{
result[i] = elementData[i];
}
return result;
}
数组在运行时知道其组件类型。 因此,要创建数组,需要在运行时提供组件类型。 但是,在您的情况下,您在运行时不知道T
因此,您不能创建真正是T[]
。 您只能返回Object[]
,或依靠某人给您一些东西,您可以在运行时从中获得类型T
您可以将返回数组中的元素转换为它们的实型。 但是您不能将数组转换为T []
Java中的数组在引入泛型的Java 5之前就存在。 因此,数组不依赖于泛型,这就是为什么我们经常在API中使用集合而不是数组的原因。 因此,Collection最终可以转换为Collection,但是Object []无法转换为另一个数组T [],它将是另一个不兼容的类型。
我认为这与以下事实有关:数组是协变的,因此您可以从T[]
Object[]
为Object[]
,因为Object
可以完成T
可以做的任何事情,但是反之则没有意义, Object
不能尽一切T
即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.