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

wax*_*ing 23 java arrays list

我遇到了一些非常基本但今天非常困惑的事情.我需要将列表转换为数组.该列表包含String实例.完美的使用示例List.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));
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个不编译.它几乎是javadoc中示例的精确副本,但编译器说如下:

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

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

<T> T[] toArray(T[] a)
Run Code Online (Sandbox Code Playgroud)

这告诉我,我不应该投.到底是怎么回事?

编辑:

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

List<?> l = Arrays.asList("a", "b", "c");
Run Code Online (Sandbox Code Playgroud)

它也有效.或者List<Object>.所以它不一定List<String>是建议的.我开始认为使用原始List类型也会改变该类中泛型方法的工作方式.

第二次编辑:

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

dfa*_*dfa 29

您忘了为List指定type参数:

List<String> l = Arrays.asList("a", "b", "c");
Run Code Online (Sandbox Code Playgroud)

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

String[] a = l.toArray(new String[0]);
Run Code Online (Sandbox Code Playgroud)

没有任何演员.

  • 语言规范已经相当复杂,所以不是为部分通用化代码提出更复杂的规则(为什么你会部分地将代码化为通用代码?),所有泛型都被删除了.我相信JDK7有-Xlint:rawtypes可以捕获这个错误. (2认同)