add (List<?extends Z>) 其中Z是一个接口。类B扩展A实现Z为什么不能用List<A&gt调用add()。

问题描述 投票:-1回答:1
 Interface Z{}

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

Class A{}

如上所述,一个简单的类A。

 Class B extends A implements Z{}

B类扩展了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的alist或类型为List的方法来调用它。 Z的实现类的超类。

类B是Z的一个实现,但也是A的一个子类,所以类A满足上面的条件.它是Z(类B)实现类的超级类。

所以当我用一个ArrayList调用add()时,为什么会出现错误。

java generics wildcard bounded-wildcard
1个回答
2
投票

想象一下,这是方法体 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 ClassCastException 在...上 A a = aaa.get(0); 行,因为它是某一子类的 Z 那不是 A.

试试吧,通过调用 add((List) aaa).

这就是为什么编译器会阻止你这么做。List<? super Z> 是一个可以安全地将 Z或任何子类。List<A> 是一个列表,可以安全地将 A或任何子类,或空;而你从列表中检索到的任何东西都将是一个 A的一个子类,或空。的一些实例。Z 的实例。A.

© www.soinside.com 2019 - 2024. All rights reserved.