为什么Java泛型的这种(错误)使用没有';不编译?
可能重复:为什么Java泛型的这种(错误)使用没有';不编译?,java,generics,Java,Generics,可能重复: 给定以下代码: import java.util.Collections; 导入java.util.List; 公开课{ //TODO:private final Some=新Some(); 私有最终部分=新部分(); 公共静态void main(字符串[]args){ 新来的人; } 公众虚无的花花公子(){ for(String str:some.getSomeStrings()){//FIXME:未编译! 系统输出打印项次(str); } } } 分类{ 公共列表GetSom
给定以下代码:
import java.util.Collections;
导入java.util.List;
公开课{
//TODO:private final Some=新Some();
私有最终部分=新部分();
公共静态void main(字符串[]args){
新来的人;
}
公众虚无的花花公子(){
for(String str:some.getSomeStrings()){//FIXME:未编译!
系统输出打印项次(str);
}
}
}
分类{
公共列表GetSomeString(){
返回集合。emptyList();
}
}
它不会编译,因为some.getSomeStrings()
返回原始列表。但是方法签名指定它返回一个列表
不知何故,它与以下事实有关:Some
有一个类型声明,但被引用为原始类型。使用对Some
的引用可修复此问题。但是该方法与类的类型声明无关
为什么编译器会这样做?如果使用泛型类的原始(非类型化)实例,那么它将被视为完全原始,即忽略所有泛型类型信息,即使被忽略的类型与被忽略的泛型类型无关
这就是为什么
private final Some<?> some = new Some();
private final Some=new Some();
…修复了错误-它使用的是Some
(尽管是通配符)首先,如果不实际使用定义的类型参数,则声明类Some
泛型是没有意义的。这实际上是问题的根源。在此模式中实例化该类型的成员字段:
private final Some some = new Some();
这是一个raw类型的声明-这是一个省略了其类型参数的泛型类型。这实际上意味着不仅它自己的类型参数T
被丢弃,而且该类方法中使用的所有泛型类型都被忽略,包括公共列表getSomeString()
中的
参数
所以解决方案其实很简单,引用Joshua Bloch的话:
不要在新代码中使用原始类型
要使其具体化,您建议的修复方法是:
private final Some<?> some = new Some();
旁注:不必在此代码中显式声明字符串参数:
return Collections.<String> emptyList();
返回集合。空列表();
编译器根据方法签名推断泛型类型,因此您可以将代码简化为:
public List<String> getSomeStrings() {
return Collections.emptyList();
}
public List getSomeStrings(){
返回集合。emptyList();
}
编辑:
说到Joshua Bloch,他在Google I/O 2011上的演讲中有一个很好的Java谜题,网址是:Collections.emptyList()??另请参见
return Collections.<String> emptyList();
public List<String> getSomeStrings() {
return Collections.emptyList();
}