java generics <? extends A> v.s <A> vs <? super A>
这可能是一个非常愚蠢的问题,但是我不明白为什么编译器会抱怨和编译。
我有两个非常简单的课程:
1 2 3 4 5 | class A { } class B extends A { } |
现在代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //block1 List<A> list = new ArrayList<>(); list.add(new A()); //ok list.add(new B()); //ok //block2 List<? extends A> extendList= new ArrayList<>(); extendList.add(new A()); //not ok, why? extendList.add(new B()); //not ok, why? //block3 List<? super A> superList = new ArrayList<>(); superList.add(new A()); //ok superList.add(new B()); //ok. why? |
号
布洛克一号我知道它为什么起作用。
块2,我有
1 2 3 4 5 | Error: no suitable method found for add(A) method java.util.Collection.add(capture#1 of ? extends A) is not applicable (argument mismatch; A cannot be converted to capture#1 of ? extends A) method java.util.List.add(capture#1 of ? extends A) is not applicable (argument mismatch; A cannot be converted to capture#1 of ? extends A) |
布洛克3,我有
我想我可能误解了
Oracle通用教程中的一句话:(https://docs.oracle.com/javase/tutorial/java/generics/upperbounded.html)
1 2 3 |
。
Block2:"据我所知,列表将接受A类型或A子类型的对象,例如B"-不!考虑
block3:再考虑一下
这里有一个场景要说明。考虑第三类:
1 2 3 4 5 | class C extends A { } List<C> cList = new ArrayList<>(); List<? extends A> extendList = cList; //this is valid. Right? Yes |
这样,失败的原因就变得很清楚了。如果允许
1 | extendList.add(new B()); |
号
但是接下来我们将添加一个不兼容的类型(
原因是边界:
埃多克斯1〔24〕
假设你的
你可以从那张单子上选一个(36),因为你知道从那张单子上选的任何东西都可以分配给一个(26),所以没有问题。注意,在块3中,你不能从列表中得到任何东西,但是你可以插入——相反。
你可以插入到
看看有效的Java第三版和KOLTIN在行动-是的,Kotlin,它有一个稍微不同的方法,这可以帮助你了解它更多。Kotlin语言把所有这些都放在了干净的规则中。