繁体   English   中英

Java /泛型/数组问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM