如果java这样做了,你可能很容易被污染列表。假设java按照您的建议做了,并允许您分配
List<Child>
到类型的变量
List<Parent>
是的。那么,这将是可能的:
static class Parent {}
static class Child extends Parent {}
static class IllegitimateChild extend Parent {}
public static void main(String args[]) {
List<Child> children = new ArrayList<>();
computeSomething(children);
Child c = children.get(0); //WTF - ClassCastException?? IllegitimateChild is not a Child
}
public static void computeSomething(List<Parent> items) {
parents.add(new IllegitimateChild());
}
为了解决这个问题,java会让您显式地声明一个有界通配符(如果您需要的话)。这允许它在编译时捕获此类错误。
public static void main(String[] args) {
List<? extends Parent> items = new ArrayList<Child>();
items.add(new IllegitimateChild()); // Compiler error
items.add(new Child()); // Compiler error
}
上面的两个编译器错误都是java所说的“这个列表中的元素类型对我来说是未知的(
?
),因此我不能允许您将此项放在此处,因为它可能违反了其他引用此列表的约定
做
知道类型。”事实上
? extends Parent
而不仅仅是
是吗?
只会真正帮助编译器推断
返回类型
方法的(例如,它知道它可以分配调用的结果
items.get(0)
给一个
Parent
变量,即使它不知道具体的类型)。