List.toArray(T[]) 的奇数泛型行为

2022-09-01 23:14:50

我遇到了一些非常基本但今天非常令人困惑的东西。我需要将列表转换为数组。该列表包含实例。使用的完美示例,因为我想要一个实例。但是,如果不将结果显式转换为 ,则无法正常工作。StringList.toArray(T[])String[]String[]

作为测试方案,我使用了以下代码:

import java.util.Arrays;
import java.util.List;

public class MainClass {
    public static void main(String args[]) {
        List l = Arrays.asList("a", "b", "c");
        String stuff[] = l.toArray(new String[0]);
        System.err.println(Arrays.asList(stuff));
    }
}

它不会编译。它几乎是javadoc中示例的精确副本,但编译器说:

MainClass.java:7: incompatible types
found   : java.lang.Object[]
required: java.lang.String[]
    String stuff[] = l.toArray(new String[0]);
                          ^

如果我添加一个强制转换到它将编译并完美运行。但这不是我在查看toArray方法的签名时所期望的:String[]

<T> T[] toArray(T[] a)

这告诉我,我不应该选角。这是怎么回事?

编辑:

奇怪的是,如果我将列表声明更改为:

List<?> l = Arrays.asList("a", "b", "c");

它也可以工作。或。因此,它不必像建议的那样。我开始认为使用原始类型也会改变该类中的泛型方法的工作方式。List<Object>List<String>List

第二次编辑:

我想我现在明白了。Tom Hawtin在下面的评论中写道,似乎是最好的解释。如果以原始方式使用泛型类型,则编译器将擦除该实例中的所有泛型信息。


答案 1

您忘记为列表指定类型参数:

List<String> l = Arrays.asList("a", "b", "c");

在这种情况下,您可以编写安全:

String[] a = l.toArray(new String[0]);

没有任何演员阵容。


答案 2

或执行

List<?> l = Arrays.asList("a", "b", "c");  

还是很奇怪