Java 编译器是否应该在泛型集合中发现此错误?
以下代码在Java 编译器是否应该在泛型集合中发现此错误?,java,generics,Java,Generics,以下代码在toArray()处抛出一个ArrayStoreException。如果toArray采用V[]并且注册表映射的值为Map,编译器不应该发现错误并报告类型冲突吗 私有地图注册; ... registry=newtreemap(String.CASE不区分大小写\u顺序)); ... void removeTargets(字符串[]clsarr,字符串hdl){ if(clsarr==null){clsarr=registry.values().toArray(新字符串[0]);} ..
toArray()
处抛出一个ArrayStoreException
。如果toArray
采用V[]
并且注册表映射的值为Map
,编译器不应该发现错误并报告类型冲突吗
私有地图注册;
...
registry=newtreemap(String.CASE不区分大小写\u顺序));
...
void removeTargets(字符串[]clsarr,字符串hdl){
if(clsarr==null){clsarr=registry.values().toArray(新字符串[0]);}
...
}
在我看来,它像是一个编译器错误。否。函数是:
T[]toArray(T[]a)
返回包含此集合中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型
其中,泛型集合中的类型为E
。因此,您可以在那里传入任何类型的变量
这是一个笨拙的设计,因为泛型类型在编译时被擦除,所以无法在运行时返回正确类型的数组。这就是为什么您必须在
toArray
调用中提供类型。在我看来,这很不雅观——传入了您想要的类型数组——但是Java没有在这里引入任何方式来提供类型注释。不是编译器错误。不过,这可能是一个库bug
Collection.toArray()
的类型是T[]toArray(T[]a)
。请注意,T
是toArray
方法的类型参数,与集合的类型参数没有关系
如果Collection.toArray
的签名是T[]toArray(T[]a)
,则会发现此错误,但这将使其难以使用,因为执行new Map[0]
是不合法的——您会得到一个“泛型数组创建”错误。泛型支持再一次“总比没有好,但仍有很多需要改进”. 谢谢你的解释。@softwaremonkey。是 啊在广泛使用的编程语言中,类型系统中有漏洞,错误可能会漏掉。这不是由于任何理论上的限制,而是由于Java数组类型的早期设计决定通过说String[]
是Object[]
来掩盖差异问题,这使得数组类型很难进入试图正确处理差异的泛型类型系统。
private Map<String,Map<String,String>> registry;
...
registry=new TreeMap<String,Map<String,String>>(String.CASE_INSENSITIVE_ORDER));
...
void removeTargets(String[] clsarr, String hdl) {
if(clsarr==null) { clsarr=registry.values().toArray(new String[0]); }
...
}