List.toArray(T )的奇数generics行为
我遇到了一些非常基本但今天非常困惑的事情。 我需要将列表转换为数组。 该列表包含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)); } }
哪个不编译。 它几乎是javadoc中示例的精确副本,但编译器说明如下:
MainClass.java:7: incompatible types found : java.lang.Object[] required: java.lang.String[] String stuff[] = l.toArray(new String[0]); ^
如果我向String[]
添加一个强制转换,它将编译并完美运行。 但是当我查看toArray方法的签名时,这不是我所期望的:
T[] toArray(T[] a)
这告诉我,我不应该投。 到底是怎么回事?
编辑:
奇怪的是,如果我将列表声明更改为:
List l = Arrays.asList("a", "b", "c");
它也有效。 或者List
。 因此它不必像建议的那样是List
。 我开始认为使用原始List
类型也会改变该类中generics方法的工作方式。
第二次编辑:
我想我现在明白了。 Tom Hawtin在下面的评论中所写的内容似乎是最好的解释。 如果以原始方式使用generics类型,则编译器将擦除该实例中的所有generics信息。
您忘了为List指定type参数:
List l = Arrays.asList("a", "b", "c");
在这种情况下,你可以写安全:
String[] a = l.toArray(new String[0]);
没有任何演员。
或者做
List> l = Arrays.asList("a", "b", "c");
还是很奇怪
List l = Arrays.asList("a", "b", "c");
这将使它编译,您使用generics来说“这是一个字符串列表”,因此toArray方法知道要返回哪种类型的数组。
那是因为你的列表包含对象,而不是字符串。 如果您将列表声明为List
,编译器会很高兴。
没有声明类型的List
将默认为“对象List>
”,而List>
表示“未知列表”。 在generics类型的世界中,“对象列表”与“字符串列表”不同,但编译器不能对“未知列表”说同样的事实。 如果您已将其声明为未知,那么就编译器而言,这没关系。
重点是将某些东西称为通配符? 不同于将其声明为Object。 在这里阅读有关通配符的更多信息