为什么List .toArray()返回Object 而不是String ? 如何解决这个问题?
有谁知道为什么Java 1.6有这种行为:
List list = ArrayList(); String[] arr = (String[]) list.toArray();
我得到一个ClassCastException,因为它返回Object []而不是String []。
我以为List.toArray()
应该返回T [] – 不是吗? 有没有人有答案为什么语言中存在这种不便? 还有如何解决这个问题? 如何从List
获取String []而不通过项目循环?
您需要传入一个数组,以便其运行时类型可以用作toArray
的提示。 尝试使用toArray(new String[0])
代替。 您还可以传入预先resize的数组。
要理解,请考虑要进行哪种类型的擦除
new T[4]
工作。 如果Java允许的话,那么擦除后最好的就是
new Object[4]
大多数toArray
实现使用java.lang.reflect.Array
来构造一个正确类型的输出数组,给定一个类型提示作为Class
传递。
因为数组从一开始就在Java中,而generics只是在Java 5中引入。并且List.toArray()
方法是在Java 1.2中引入的,在generics存在之前,因此它被指定为返回Object[]
。 现在许多现有代码都希望List.toArray()
返回Object[]
,因此现在无法更改它。
此外,generics在运行时被擦除,因此如果需要, ArrayList
甚至无法构造适当类型的数组。
这方面的漏洞是List.toArray(T[])
方法,它会返回一个正确类型的数组,前提是你给它一个正确类型的数组,这样它就知道要使用什么类型。
要了解发生这种情况的原因,只需查看Collection.toArray()
的javadoc,然后查看Collection.toArray(T[] a)
方法。 还要记住,Java中的generics在运行时被擦除。
原因有两个:
-
该方法在Generics之前,并且在不破坏向后兼容性的情况下无法更改签名。
-
在任何情况下,由于
List
的构造没有Class
,因此实现无法构造类型为T
的数组。
解决方法是使用:
List list = new ArrayList<>(); list.add("Sputnik"); list.add("Explorer"); //String[] str = list.toArray();
这必然抛出一个:不兼容的类型:Object []无法转换为String []错误
Instead use: String[] str = list.toArray(new String[0]); or String[] str = list.toArray(new String[list.size()]);