11

可能重复:
如果实例没有分配泛型类型,则每个循环问题的泛型

有人可以澄清为什么iterate1()编译器(Java 1.6)不接受吗?我不明白为什么iterate2()而且iterate3()好多了。

import java.util.Collection;
import java.util.HashSet;

public class Test<T> {

    public Collection<String> getCollection() {
        return new HashSet<String>();
    }

    public void iterate1(Test test) {
        for (String s : test.getCollection()) {
            // ...
        }
    }

    public void iterate2(Test test) {
        Collection<String> c = test.getCollection();
        for (String s : c) {
            // ...
        }
    }

    public void iterate3(Test<?> test) {
        for (String s : test.getCollection()) {
            // ...
        }
    }


}

编译器输出:

$ javac Test.java
Test.java:11: incompatible types
found   : java.lang.Object
required: java.lang.String
  for (String s : test.getCollection()) {
                                              ^
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
4

1 回答 1

14

当您使用原始类型(例如,Test而不是Test<T>,编译器将其(JLS 4.8)视为该类型的擦除JLS 4.6) - 完全擦除泛型,无论它们是否使用类型参数:

如果构造函数或方法的签名被擦除,构造函数或方法的类型参数(第 8.4.4 节)和方法的返回类型(第 8.4.5 节)也会被擦除。

基本上,编译器将原始类型的使用视为您根本不希望该代码知道泛型的指示 - 因此方法签名被删除为:

public Collection getCollection()

...因此编译时错误,因为推断的元素类型是Object,根据JLS 14.14.2

于 2012-10-02T15:47:36.747 回答