有人知道Java 1.6为什么会出现这种情况:
List<String> list = ArrayList<String>();
String[] arr = (String[]) list.toArray();
我得到一个ClassCastException,因为它返回Object []而不是String []。
我想List<T>.toArray()
应该返回T [] - 不是吗?有没有人能够回答为什么语言中存在这种不便?
还有如何解决这个问题?如何在不通过项目循环的情况下从List<String>
获取String []?
答案 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)
原因有两个:
该方法在Generics之前,他们无法在不破坏向后兼容性的情况下更改签名。
在任何情况下,由于List
的构造没有Class<T>
,因此实现无法构造类型为T
的数组。
答案 4 :(得分:1)
解决方法是使用:
Instead use:
String[] str = list.toArray(new String[0]);
or
String[] str = list.toArray(new String[list.size()]);
这必然抛出一个:不兼容的类型:Object []无法转换为String []错误
{{1}}