可能的重复项:
每个循环问题的泛型(如果实例未分配泛型类型)
有人可以澄清为什么编译器不接受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。