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

发布于 2024-12-12 06:11:08 字数 365 浏览 0 评论 0原文

有谁知道为什么 Java 1.6 有这种行为:

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

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

我以为 List.toArray() 应该返回 T[] - 不?有谁知道为什么语言中存在这种不便? 以及如何解决这个问题?如何从 List 获取 String[] 而不循环遍历项目?

Does anybody know why Java 1.6 has this behaviour:

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

And I get a ClassCastException, because it returns Object[] and not 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柳絮泡泡 2024-12-19 06:11:08

您需要传入一个数组,以便 toArray 可以将其运行时类型用作提示。尝试使用 toArray(new String[0]) 代替。您还可以传入预先确定大小的数组。

要理解这一点,请考虑需要执行什么类型的擦除才能起作用

new T[4]

。如果 Java 允许这样做,那么它在擦除后所能做的最好的事情就是

new Object[4]

大多数 toArray 实现都使用 java.lang.reflect.Array 在给定的情况下构造正确类型的输出数组类型提示作为

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.

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

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.

标点 2024-12-19 06:11:08

因为数组从一开始就存在于 Java 中,而泛型是在 Java 5 中才引入的。而 List.toArray() 方法是在 Java 1.2 中引入的,在泛型存在之前,所以它被指定为返回对象[]。许多现有代码现在期望 List.toArray() 返回 Object[],因此现在无法更改。

此外,泛型会在运行时被删除,因此 ArrayList 甚至无法根据需要构造正确类型的数组。

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

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.

Furthermore, generics are erased at runtime, so ArrayList couldn't even construct an array of the proper type if it wanted to.

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.

黒涩兲箜 2024-12-19 06:11:08

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

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.

爱的故事 2024-12-19 06:11:08

从 Java 11 开始,它比 String[] str = list.toArray(new String[0])String[] str = list.toArray(new String[list.size()) 更容易]):

String[] str = list.toArray(String[]::new);

Since Java 11 it's even easier than String[] str = list.toArray(new String[0]) or String[] str = list.toArray(new String[list.size()]):

String[] str = list.toArray(String[]::new);
浮生未歇 2024-12-19 06:11:08

原因有两个:

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

  2. 无论如何,由于 List 是在没有 Class 的情况下构造的,因此实现无法构造 T< 类型的数组/code>.

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 List is constructed without a Class<T> there is no way for the implementation to construct an array of type T.

飘然心甜 2024-12-19 06:11:08

解决方法是使用:

       List<String> 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()]);

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

       Instead use:

        String[] str = list.toArray(new String[0]);
        or
        String[] str = list.toArray(new String[list.size()]);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文