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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:57:39  来源:igfitidea点击:

why does List<String>.toArray() return Object[] and not String[]? how to work around this?

javagenerics

提问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 toArrayimplementations use java.lang.reflect.Arrayto 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 ArrayListcouldn'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:

原因有二:

  1. The method preceded Generics and they couldn't change the signature without breaking backwards compatibility.

  2. In any case, as the Listis constructed without a Class<T>there is no way for the implementation to construct an array of type T.

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

  2. 在任何情况下,由于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()]);