Java 抽象类上参数化方法的奇怪行为
有人能告诉我为什么会出现编译错误吗?我不明白为什么在第二个for循环中对A的强制转换会导致strings()返回对象的常规列表Java 抽象类上参数化方法的奇怪行为,java,generics,abstract-class,parameterized,Java,Generics,Abstract Class,Parameterized,有人能告诉我为什么会出现编译错误吗?我不明白为什么在第二个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.pri
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 {
}
}
import java.util.ArrayList;
导入java.util.List;
公共E类{
公共静态void main(字符串[]args){
对于(字符串s:new D().strings()){
System.out.println(“s=“+s”);
}
对于(字符串s:((A)新的D()).strings()){
System.out.println(“s=“+s”);
}
}
静态类D扩展了{
}
静态抽象类A{
列表字符串(){
返回新的ArrayList(){{
添加(“Foo”);
添加(“酒吧!”);
}};
}
}
静态B类{
}
静态类C扩展了B{
}
}
这是非专利药的怪癖吗
谢谢你,克里斯蒂安在电话里:
for (String s : ((A) new D()).strings()) {
您正在强制转换为原始类型A
,因此会丢失那里的类型参数信息。在Java中,原始类型上的任何使用方法或字段也会产生原始类型(即使所有参数化信息都可用)——从技术上讲是原始类型还是非参数化类型。因此A.string()
被视为原始类型List
,而不是List
正如JSL在中指定的:
构造函数(§8.8)、实例方法(§8.8、§9.4)或非静态字段(§8.3)的类型未从其超类或超接口继承的原始类型C的M是在对应于C的泛型声明中删除其类型。原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同
那真的很有趣。这就解释了为什么如果你选择A而不是A,它会起作用。在这种情况下,您仍在使用键入的类。+1感谢您的回答。我删除了我自己的答案,那没有这个好。@Shaun,是的。在某种程度上,这是一个让你恼火的问题,所以要避免使用原始类型!谢谢,这就解释了。顺便说一句,在1.6.0_17上测试它的人之所以成功,是因为在通过msn/adium粘贴代码时使用了pebkac。。。演员阵容被删除了,可能是因为某些格式问题。我的错。