有人可以告诉我为什么会出现编译错误吗?我不明白为什么在第二个for循环中转换为A会导致strings()返回一般的对象列表。
import java.util.ArrayList;
import java.util.List;
public class E {
public static void main(String[] args) {
for (String s : new D().strings()) {
System.out.println("s = " + s);
}
for (String s : ((A) new D()).strings()) {
System.out.println("s = " + s);
}
}
static class D extends A<C> {
}
static abstract class A<T extends B> {
List<String> strings() {
return new ArrayList<String>() {{
add("Foo");
add("Bar!");
}};
}
}
static class B {
}
static class C extends B {
}
}
这是一个泛型怪癖吗?
谢谢,克里斯蒂安
答案 0 :(得分:7)
在行中:
for (String s : ((A) new D()).strings()) {
您正在转换为原始类型A
,因此您丢失了那里的类型参数信息。在Java中,原始类型上的任何使用方法或字段也会导致原始类型(即使所有参数化信息都可用) - 原始类型或技术上非参数化。因此,A.string()
被视为原始类型List
,而不是List<String>
。
正如JSL在Section 4.8中指定的那样:
未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.8节,第9.4节)或非静态字段(第8.3节)M的类型是擦除与C对应的泛型声明中的类型。原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同。