添加 (List<? extends Z>) 其中 Z 是一个接口。 Class B extends A implements Z 为什么我们不能用 List<A> 调用 add()

add (List<? extends Z>) where Z is an interface . Class B extends A implements Z why cant we call add() with a List<A>

 Interface Z{}

考虑上面声明的一个简单接口 Z。

Class A{}

A 简单 class A 如上所述。

 Class B extends A implements Z{}

Class B 扩展 class A 并实现接口 Z

class Test{

static void add(List<? super Z>){}

public static void main(String[]  args){
List<A> aaa= new ArrayList<>();
add(aaa);  //Gives error here
} 
}

上面测试class中的add方法有一个参数List,据我所知我可以用Z类型的列表或super[=30类型的列表来调用它=] 的实现 class Z.

class B 是 Z 的实现,但也是 A 的子级,因此 class A 满足上述条件。它是 (class 的超 class ] B) Z(class B).

的实现 class

所以当我用 ArrayList 调用 add() 时为什么会报错。

假设这是add的方法体。这编译得很好:

static void add(List<? super Z> list){
  list.add(new Z() {});  // Fine.
}

此外,编译正常。

List<A> aaa= new ArrayList<>();
// ... Something.
A a = aaa.get(0);

现在,如果 ... Something 是:

add(aaa);  // Compiler error!

如果那个编译器错误没有发生会发生什么? A a = aaa.get(0); 行上的 ClassCastException,因为它是 Z 的某个子类的实例,而不是 A.

尝试一下,调用 add((List) aaa)

这就是编译器阻止您这样做的原因。 List<? super Z> 是一个列表,可以安全地向其中添加 Z 或任何子类的实例。 List<A> 是一个列表,可以安全地向其中添加 A 或任何子类的实例,或者为 null;并且您从列表中检索到的任何内容都将是 A、子类或 null。 Z 的某些实例不是 A.

的实例