本文介绍了ArrayList.toArray() 中的 Java 泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设你有一个如下定义的数组列表:

Say you have an arraylist defined as follows:

ArrayList<String> someData = new ArrayList<>();

稍后在您的代码中,由于泛型,您可以这样说:

Later on in your code, because of generics you can say this:

String someLine = someData.get(0);

编译器完全知道它将获得一个字符串.耶泛型!但是,这将失败:

And the compiler knows outright that it will be getting a string. Yay generics! However, this will fail:

String[] arrayOfData = someData.toArray();

toArray() 将始终返回一个对象数组,而不是定义的泛型数组.为什么 get(x) 方法知道它返回的是什么,但 toArray() 默认为 Objects?

toArray() will always return an array of Objects, not of the generic that was defined. Why does the get(x) method know what it is returning, but toArray() defaults to Objects?

推荐答案

如果你看一下 ArrayList 类,就像:

If you look at the implementation of toArray(T[] a) of ArrayList<E> class, it is like:

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

此方法的问题在于您需要传递相同泛型类型的数组.现在考虑如果这个方法不接受任何参数,那么实现将类似于:

Problem with this method is that you need to pass array of the same generic type. Now consider if this method do not take any argument then the implementation would be something similar to:

public <T> T[] toArray() {
    T[] t = new T[size]; // compilation error
    return Arrays.copyOf(elementData, size, t.getClass());
}

但这里的问题是您不能在 Java 中创建泛型数组,因为编译器并不确切知道 T 代表什么.换句话说,创建不可具体化类型的数组(JLS §4.7) 在 Java 中是不允许的.

But the problem here is that you can not create generic arrays in Java because compiler does not know exactly what T represents. In other words creation of array of a non-reifiable type (JLS §4.7) is not allowed in Java.

来自 Array Store Exception 的另一个重要引述(JLS §10.5):

Another important quote from Array Store Exception (JLS §10.5):

如果数组的组件类型不可具体化(第 4.7 节),则 Java 虚拟机无法执行上一段.这就是为什么数组创建表达式带有禁止不可具体化的元素类型(第 15.10.1 节).

这就是 Java 提供重载版本的原因 toArray(T[] a).

That is why Java has provided overloaded version toArray(T[] a).

我将覆盖 toArray() 方法以告诉它它将返回一个E的数组.

因此,您应该使用 toArray(T[] a) 而不是覆盖 toArray().

So instead of overriding toArray(), you should use toArray(T[] a).

无法从 Java 创建类型参数的实例Doc 也可能对您感兴趣.

Cannot Create Instances of Type Parameters from Java Doc might also be interesting for you.

这篇关于ArrayList.toArray() 中的 Java 泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-15 06:09