添加(列表<?扩展 Z>),其中 Z 是一个接口。类 B 扩展 A 实现 Z 为什么我们不能用列表<A>调用 add()


Interface Z{}

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

Class A{}

上面声明的一个简单的类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
} 
}

上面测试类中的add方法有一个参数List,据我所知,我可以用类型为Z的List或类型为Z实现类的superclass的列表来调用它。

类B是Z的实现,但也是a的子类,因此类a满足上述条件。它是Z(类B(的实现类(B类(的超类。

所以,当我用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,因为它是不是AZ的某个子类的实例。

通过调用add((List) aaa)来尝试它。

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

相关内容

  • 没有找到相关文章

最新更新