为什么List <string> .toArray()返回Object []而不是String []?如何解决这个问题?</string>

时间:2011-10-26 22:34:10

标签: java generics

有人知道Java 1.6为什么会出现这种情况:

List<String> list = ArrayList<String>();
String[] arr = (String[]) list.toArray();

我得到一个ClassCastException,因为它返回Object []而不是String []。

我想 List<T>.toArray()应该返回T [] - 不是吗?有没有人能够回答为什么语言中存在这种不便? 还有如何解决这个问题?如何在不通过项目循环的情况下从List<String>获取String []?

5 个答案:

答案 0 :(得分:21)

您需要传入一个数组,以便它的运行时类型可以用作toArray的提示。请尝试使用toArray(new String[0])。您也可以传入预先调整大小的数组。

要理解,请考虑使用什么类型的擦除

new T[4]

的工作。如果Java允许这样做,那么它最好能够在删除后进行删除

new Object[4]

大多数toArray实现使用java.lang.reflect.Array来构造一个正确类型的输出数组,给定一个类型提示作为Class传递。

答案 1 :(得分:13)

因为数组从一开始就使用Java,而泛型只是在Java 5中引入。而{1}}方法是在Java 1.2中引入的,在泛型存在之前,因此指定返回{{1 }}。现在许多现有代码都希望List.toArray()返回Object[],因此现在无法更改。

此外,泛型会在运行时被删除,因此如果需要,List.toArray()甚至无法构造正确类型的数组。

这方面的漏洞是List.toArray(T[])方法,如果你给它一个正确类型的数组,它将返回一个正确类型的数组,以便它知道要使用的类型。

答案 2 :(得分:3)

要了解发生这种情况的原因,只需查看Collection.toArray()的javadoc,然后查看Collection.toArray(T[] a)方法。还要记住,Java中的泛型会在运行时被删除。

答案 3 :(得分:1)

原因有两个:

  1. 该方法在Generics之前,他们无法在不破坏向后兼容性的情况下更改签名。

  2. 在任何情况下,由于List的构造没有Class<T>,因此实现无法构造类型为T的数组。

    < / LI>

答案 4 :(得分:1)

解决方法是使用:

       Instead use:

        String[] str = list.toArray(new String[0]);
        or
        String[] str = list.toArray(new String[list.size()]);

这必然抛出一个:不兼容的类型:Object []无法转换为String []错误

{{1}}