为什么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();
  }