java 为什么 List<String>.toArray() 返回 Object[] 而不是 String[]?如何解决这个问题?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7909747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
why does List<String>.toArray() return Object[] and not String[]? how to work around this?
提问by justadreamer
Does anybody know why Java 1.6 has this behaviour:
有谁知道为什么 Java 1.6 有这种行为:
List<String> list = ArrayList<String>();
String[] arr = (String[]) list.toArray();
And I get a ClassCastException, because it returns Object[] and not String[].
我得到一个 ClassCastException,因为它返回 Object[] 而不是 String[]。
I thought
List<T>.toArray()
should return T[] - no? Does anyone have an answer why this inconvenience exists in the language?
And also how to work around this? How do I get a String[] from List<String>
without looping thru the items?
我想
List<T>.toArray()
应该返回 T[] - 不是吗?有没有人知道为什么语言中存在这种不便?以及如何解决这个问题?如何在List<String>
不循环遍历项目的情况下获取 String[] ?
采纳答案by Mike Samuel
You need to pass in an array so its runtime type can be used as a hint by toArray
. Try toArray(new String[0])
instead. You can also pass in a pre-sized array.
您需要传入一个数组,以便其运行时类型可以用作toArray
. 试试吧toArray(new String[0])
。您还可以传入预先确定大小的数组。
To understand, consider what type erasure would have to do to make
要理解,请考虑要进行何种类型的擦除
new T[4]
work. If Java allowed that, the best it could do post erasure is
工作。如果 Java 允许这样做,那么它在擦除后能做的最好的事情是
new Object[4]
Most toArray
implementations use java.lang.reflect.Array
to construct an output array of the right type given a type hint passed as a Class
.
大多数toArray
实现用于java.lang.reflect.Array
构造正确类型的输出数组,给定作为Class
.
回答by Daniel Pryden
Because arrays have been in Java since the beginning, while generics were only introduced in Java 5. And the List.toArray()
method was introduced in Java 1.2, before generics existed, and so it was specified to return Object[]
. Lots of existing code now expects List.toArray()
to return Object[]
, so it can't be changed now.
因为数组从一开始就在Java中,而泛型只在Java 5中List.toArray()
被引入。并且该方法是在Java 1.2中引入的,在泛型存在之前,所以它被指定为 return Object[]
。许多现有代码现在都希望List.toArray()
return Object[]
,因此现在无法更改。
Furthermore, generics are erased at runtime, so ArrayList
couldn't even construct an array of the proper type if it wanted to.
此外,泛型在运行时ArrayList
会被擦除,因此如果需要,甚至无法构造正确类型的数组。
The loophole for this is the List.toArray(T[])
method, which will return you an array of the correct type, provided you give it an array of the correct type so it knows what type to use.
漏洞在于List.toArray(T[])
方法,它会返回一个正确类型的数组,前提是你给它一个正确类型的数组,这样它就知道要使用什么类型。
回答by Costi Ciudatu
To understand why that happens, just have a look at the javadoc for Collection.toArray()
and then look at the Collection.toArray(T[] a)
method. Also keep in mind that generics in Java are erased at runtime.
要了解为什么会发生这种情况,只需查看 javadoc forCollection.toArray()
然后查看Collection.toArray(T[] a)
方法。还要记住,Java 中的泛型在运行时会被删除。
回答by user207421
The reasons are two:
原因有二:
The method preceded Generics and they couldn't change the signature without breaking backwards compatibility.
In any case, as the
List
is constructed without aClass<T>
there is no way for the implementation to construct an array of typeT
.
该方法在泛型之前,他们无法在不破坏向后兼容性的情况下更改签名。
在任何情况下,由于
List
是在没有 aClass<T>
的情况下构造的,因此实现无法构造类型为 的数组T
。
回答by Ajay Vijayasarathy
Workaround will be to use:
解决方法是使用:
List<String> list = new ArrayList<>();
list.add("Sputnik");
list.add("Explorer");
//String[] str = list.toArray();
This is bound to throw an : incompatible types: Object[] cannot be converted to String[] error
这必然会抛出:不兼容的类型:Object[] 无法转换为 String[] 错误
Instead use:
String[] str = list.toArray(new String[0]);
or
String[] str = list.toArray(new String[list.size()]);