返回List <e> toArray()方法的类型</e>

时间:2014-06-16 06:50:58

标签: java list oop

根据hereList<E>.toArray()方法返回Object[]。除非您使用T[],否则它无法返回<T> T[] toArray(T[] a)。为什么不能返回E[],因为我们将其声明为List<E>

2 个答案:

答案 0 :(得分:1)

长话短说:类型擦除(以及向后兼容性,在某种程度上)。

Java的泛型以一种相当有趣的方式实现 - 它们只存在于编译阶段,它们用于类型检查。然后在名为 type erasure 的过程中删除它们,其中每个泛型类型的上限(Object替换为无界类型,例如List<E>(注意:那里)有一些例外,但在这种情况下这些并不重要)

因此,在运行时,泛型类实际上并不知道泛型类型应该表示的对象的确切类型。因此,List<E>的实现仅知道它们包含Object类型的对象,而不是类型E

因此,toArray()实际上不可能返回E[],因为执行此类操作所需的信息在运行时是不可用的。这就是toArray(T[])存在的原因 - T[]只能在运行时提供所需的类型信息时返回 - 在这种情况下,通过提供的数组,因为数组保持类型的知识他们持有。


此外,我怀疑向后兼容性是返回Object[]的部分原因。自从引入了Collections API(我认为是1.2或1.3)之后,List已经出现了,这是在引入泛型之前(1.5)。因此,没有E[]返回,因为尚未存在的返回机制。因此,对于API稳定性和向后兼容性,保留了Object[]返回类型。

认为Object[]更改为E[]不会破坏任何正常工作的代码,因为数组是协变的,但我并不完全相信会是这样的。

答案 1 :(得分:-1)

ArrayList将对象存储在数组中。调用toArray()会返回该数组的副本。

实施是:

public Object[] toArray() {
    return Arrays.copyOf(elementData, size);
}

此处elementData为:

private transient Object[] elementData;

这是ArrayList存储数据的对象数组。

要返回T[],您需要使用toArray(T[] a)。您只需传递一个类型为T的新数组。

这是ArrayList中的实施:

public <T> T[] toArray(T[] a) {
    if (a.length < size)        
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());

    System.arraycopy(elementData, 0, a, 0, size);

    if (a.length > size)
        a[size] = null;

    return a;
}

如果LinkedList此方法创建Object[],则从头开始迭代所有节点,并将元素复制到该数组中。以下是实施:

public Object[] toArray() {
    Object[] result = new Object[size];
    int i = 0;

    for (Entry<E> e = header.next; e != header; e = e.next)
        result[i++] = e.element;

    return result;
}

否定选民请发表评论。