假设你有:
public interface A {}
public class B implements A {}
public class C {
void foo (List<A>) {}
}
public class Test {
//Declaration one
List<A> x = new List<A>();
//Declaration two
List<A> x = new List<B>();
B b = new B();
x.add(b);
new C().foo(x);
}
现在显然声明一个是正确的方法,并且你在声明二上收到编译错误。我想知道为什么Java选择以这种特定方式强制执行类型安全;如果猫的列表仍然是一个动物列表,为什么一个方法期待一群动物在收到一堆猫时不愿意?
好奇,最重要的是 - 并且有机会更好地完善我的知识。
干杯, 戴夫。
答案 0 :(得分:9)
Java泛型不是协变。如果你能做到这一点:
ArrayList<Animal> x = new ArrayList<Cat>();
然后你就能做到:
x.add(new Dog());
违反了ArrayList<Cat>
只能容纳Cat
个对象(或子类对象)的概念。
请阅读此内容以获取更多详细信息:Java theory and practice: Generics gotchas。
答案 1 :(得分:9)
为什么一种方法会让一群动物不愿意接受一堆猫?
因为您可以将任何动物添加到该列表中,而不仅仅是猫。这可能会产生一个包含狗的猫的列表,如下所示:
来电者仍然认为这是一张猫和一只狗的名单,当呼叫者试图让他们跌倒时,他们会摔倒。
答案 2 :(得分:0)
直接使用“extends”代替类:
List<? extends A>x;
如果您只使用该类作为泛型,那么所有元素都只属于此类。