Java 对泛型对象使用非类型化引用时,在成员类型集合上迭代失败
可能重复:Java 对泛型对象使用非类型化引用时,在成员类型集合上迭代失败,java,generics,Java,Generics,可能重复: 有人能解释一下为什么编译器(Java 1.6)不接受iterate1()?我不明白为什么iterate2()和iterate3()要好得多 import java.util.Collection; import java.util.HashSet; public class Test<T> { public Collection<String> getCollection() { return new HashSet<Str
有人能解释一下为什么编译器(Java 1.6)不接受
iterate1()
?我不明白为什么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()) {
// ...
}
}
}
当您使用原始类型(例如,Test
而不是Test
)时,编译器将其()视为该类型的擦除()-这将完全擦除泛型,无论泛型是否使用类型参数:
如果构造函数或方法的签名被删除,则构造函数或方法的类型参数(§8.4.4)和方法的返回类型(§8.4.5)也会被删除
基本上,原始类型的使用被编译器视为一种指示,表明您根本不希望该代码知道泛型-因此方法签名被擦除为:
public Collection getCollection()
…因此出现编译时错误,因为推断的元素类型是
对象
,根据。应该公共集合getCollection()
是公共集合getCollection()
?我没有可用的编译器来测试这两者之间的差异。在这里的讨论中回答-不,我的意图是使用集合。我只是不明白为什么我不能使用非类型引用类。@Arham非常好。该问题的关键短语:“如果你使用原始类型(你不应该这样做)编译器将删除该实例的所有泛型信息,即使它不是类型参数T,以使其与1.5之前的代码兼容。“现在我理解了iterate1()和iterate3()之间的区别。但是,仍然不理解iterate1()和iterate2()之间的区别。@AlexanderPavlov:我希望iterate2()
给出关于泛型类型安全的警告,Xlint显示从集合
到集合
的未经检查的转换。是的,它给出了。但不清楚为什么它在iterate1()中给出错误,在iterate2()中给出警告。我在这两种方法中都使用原始类型,所以泛型应该被删除。@AlexanderPavlov:因为在iterate2()
中,您首先显式地将原始类型分配给泛型类型(Collection
)。这是未经检查的转换,但它是有效的转换。
public Collection getCollection()