为什么Collection<E>.toArray()
(非参数化方法)返回Object[]
?
这是有意识做出的决定之一吗?如果需要,该方法是否有任何理由toArray()
无法返回 a E[]
?
为什么Collection<E>.toArray()
(非参数化方法)返回Object[]
?
这是有意识做出的决定之一吗?如果需要,该方法是否有任何理由toArray()
无法返回 a E[]
?
T
这是因为在不知道类型的情况下无法实例化类型数组Class<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;
}
Java 中的泛型是使用一种称为类型擦除的技术实现的。这意味着泛型类的实例没有关于其泛型类型的任何信息。考虑这个
List<String> list = new ArrayList<String>();
list.toArray();
由于 list 不知道它的泛型类型,它只能创建 Object[]
数组容器具有关联的项数据类型,在运行时保留。如果您构造一个 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 不知道在运行时要创建什么特定的数组类型。