Mic*_*wan 7 java generics foreach raw-types
在Java中的for-each循环中使用泛型时,我遇到了一个奇怪的编译器错误.这是一个Java编译器错误,还是我真的在这里遗漏了什么?
这是我的全班:
public class Generics<T extends Object> {
public Generics(T myObject){
// I didn't really need myObject
}
public List<String> getList(){
List<String> list = new ArrayList<String>();
list.add("w00t StackOverflow");
return list;
}
public static void main(String...a){
Generics generics = new Generics(new Object());
for(String s : generics.getList()){
System.out.println(s);
}
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨带有for-each的行:"类型不匹配无法从元素类型Object转换为String."
如果我进行这种微妙的改变,它会编译:
public static void main(String...a){
Generics<?> generics = new Generics(new Object());
for(String s : generics.getList()){
System.out.println(s);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道getList()确实使用泛型,但它在我认为完全不相关的方式中使用它们.我可以理解这一点,如果我试图迭代T类型的东西并getList()返回一个List<T>或者什么东西,但事实并非如此.返回类型getList()应该与T完全无关,不应该关心我是否使用我的Generics对象的原始类型......对吗?难道这些不完全无关,还是我真的在这里遗漏了什么?
请注意,如果我这样做,代码也会编译,我认为它应该与第一个相同:
public static void main(String...a){
Generics generics = new Generics(new Object());
List<String> list = generics.getList();
for(String s : list){
System.out.println(s);
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 12
不同之处在于,当您使用原始类型时,成员签名中的所有通用引用也会转换为其原始表单.所以你有效地调用一个现在有这样签名的方法:
List getList()
Run Code Online (Sandbox Code Playgroud)
现在,为什么你的最终版本会编译 - 尽管如此,如果你使用的话会有一个警告-Xlint:
Generics.java:16: warning: [unchecked] unchecked conversion
List<String> list = generics.getList();
^
Run Code Online (Sandbox Code Playgroud)
这类似于:
List list = new ArrayList();
List<String> strings = list;
Run Code Online (Sandbox Code Playgroud)
......也会编译,但会发出警告-Xlint.
故事的寓意:不要使用原始类型!