【问题标题】:Why does Collection<E>#toArray() not return E[]?为什么 Collection<E>#toArray() 不返回 E[]?
【发布时间】:2013-02-23 07:17:25
【问题描述】:

为什么Collection&lt;E&gt;.toArray()(非参数化方法)返回Object[]

这是有意识做出的决定之一吗?如果toArray() 方法想要返回E[],有什么原因吗?

【问题讨论】:

  • 类型擦除是原因。 java 在运行时不知道 T 是什么 - 因此它无法创建适当类型的数组。 toArray 的另一个“类型安全”变体需要一个具有正确类型(在编译时固定!)的“原型”数组,它可以复制。
  • 这是历史性的。该方法早于泛型,并保持其现有形式以避免破坏遗留代码。
  • 我不太确定。我看不出有任何方法可以在该方法中获得E 的类。
  • Why does Java's Collection<E>.toArray() return an Object[] rather than an E[]? 的可能副本。请忽略我在投票时发布的帖子 - 我粘贴了错误的链接。

标签: java arrays generics collections


【解决方案1】:

这是因为在不知道 Class&lt;T&gt; 类型的情况下无法实例化 T 类型的数组。将此与toArray(T[] array) 进行对比,它具有以下来源(来自LinkedList 的示例)。请注意,传入的数组不仅用作可能的容器,而且可能实例化该类型的新数组。如果T 不是E 的超类,此代码将引发异常;如果无法将对象添加到数组中。

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
    if (a.length < size)
        a = (T[])java.lang.reflect.Array.newInstance(
                            a.getClass().getComponentType(), size);
    int i = 0;
    Object[] result = a;
    for (Node<E> x = first; x != null; x = x.next)
        result[i++] = x.item;

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

    return a;
}

【讨论】:

    【解决方案2】:

    Java 中的泛型是使用一种称为类型擦除的技术实现的。这意味着泛型类的实例没有关于其泛型类型的任何信息。考虑一下这个

    List<String> list = new ArrayList<String>();
    list.toArray();
    

    由于 list 不知道它的泛型类型,它只能创建 Object[]

    【讨论】:

      【解决方案3】:

      数组容器具有关联的项数据类型,在运行时保留。如果你构造一个 Object 数组然后添加字符串,这个对象将不能转换为 String[]:

          Object[] objArr = new Object[] {"a", "b"};
          String[] strArr = (String[]) objArr; //Produces ClassCastException
      

      当您将不正确类型的项目添加到数组时,您还可以注意到在运行时如何使用此数组属性:

          String[] strArr = new String[] {"a", "b"};
          Object[] objArr = (Object[]) strArr; //Legal this time
          objArr[0] = 15; //Produces ArrayStoreException
      

      泛型类型参数在运行时被删除,因此当您调用 toArray() 时,JVM 不知道在运行时要创建什么特定的数组类型。

      【讨论】:

        猜你喜欢
        • 2011-09-04
        • 1970-01-01
        • 2010-11-06
        • 2014-08-02
        • 1970-01-01
        • 2012-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多