对泛型对象使用非类型化引用时,循环访问成员类型化集合失败



可能的重复项:
每个循环问题的泛型(如果实例未分配泛型类型)

有人可以澄清为什么编译器不接受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

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

如果构造函数

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

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

public Collection getCollection()

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

最新更新