为什么Java编译器抱怨对原始类型使用foreach? [英] Why does the Java Compiler complain on using foreach with a raw type?

查看:131
本文介绍了为什么Java编译器抱怨对原始类型使用foreach?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中的for-each循环中使用泛型时,出现了一个奇怪的编译器错误。这是一个Java编译器错误,还是我真的在这里丢失的东西?



这是我的整个类:

  public class Generics< T extends Object> {
public Generics(T myObject){
//我真的不需要myObject
}

public List< String> getList(){
List< String> list = new ArrayList< String>();
list.add(w00t StackOverflow);
返回列表;


public static void main(String ... a){
泛型泛型= new泛型(new Object());
for(String s:generics.getList()){
System.out.println(s);





$ b

编译器抱怨
如果我做了这个微妙的变化,它编译:

pre> public static void main(String ... a){
Generics<?>泛型= new泛型(new Object());
for(String s:generics.getList()){
System.out.println(s);




我知道 getList() 确实使用了泛型,但它在我认为是完全不相关的方式中使用它们。我可以理解这一点,如果我试图迭代类型T的东西, getList()返回一个 List< T> 或什么的,但这不是这种情况。返回类型的 getList()应该与T完全没有关系,不应该在意我是否使用我的泛型对象的原始类型或不正确?这些应该不是完全不相关的,或者我真的在这里丢失了什么?



请注意,代码也编译,如果我这样做,我认为应该是相当于第一个也是:

pre $ public static void main(String ... a){
泛型泛型= new泛型(new Object());
列表< String> list = generics.getList();
for(String s:list){
System.out.println(s);


$ / code $ / pre

解决方案

不同之处在于,当你使用原始类型时,所有成员签名中的泛型引用都被转换为原始格式。所以有效地你调用一个方法,现在有这样的签名:

$ p $ List getList()

code>

现在至于为什么你的最终版本编译 - 尽管它,如果你使用 -Xlint

  Generics.java:16:warning:[unchecked] unchecked conversion 
List< ;字符串> list = generics.getList();

类似于:

  List list = new ArrayList(); 
列表< String> strings = list;

...也可以编译,但在 -Xlint



故事的寓意:不要使用原始类型!

I got a strange compiler error when using generics within a for-each loop in Java. Is this a Java compiler bug, or am I really missing something here?

Here is my whole class:

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);
    }
  }
}

The compiler is complaining about the line with the for-each: "Type mismatch cannot convert from element type Object to String."
If I make this subtle change, it compiles:

public static void main(String...a){
  Generics<?> generics = new Generics(new Object());
  for(String s : generics.getList()){
    System.out.println(s);
  }
}

I know getList() does use generics, but it uses them in what I thought was a completely unrelated way. I could understand this if I were trying to iterate over something of type T and getList() returned a List<T> or something, but that's not the case here. The return type of getList() should have absolutely nothing to do with T and shouldn't care whether I use the raw type for my Generics object or not...right? Shouldn't these be completely unrelated, or am I really missing something here?

Note that the code also compiles if I do this, which I thought should have been equivalent to the first as well:

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);
  }
}

解决方案

The difference is that when you use the raw type, all the generic references within the member signatures are converted to their raw forms too. So effectively you're calling a method which now has a signature like this:

List getList()

Now as for why your final version compiles - although it does, there's a warning if you use -Xlint:

Generics.java:16: warning: [unchecked] unchecked conversion
    List<String> list = generics.getList();
                                        ^

This is similar to:

 List list = new ArrayList();
 List<String> strings = list;

... which also compiles, but with a warning under -Xlint.

The moral of the story: don't use raw types!

这篇关于为什么Java编译器抱怨对原始类型使用foreach?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆