I read this post about contravariance:
Let’s now introduce another wildcard:
? super. Given a supertypeBof
a typeA, thenC<B>is a subtype ofC<? super A>:
List<Fruit> fruits = new ArrayList<Fruit>();
List<? super Apple> = fruits;
but why C<B> is a subtype and not a supertype?
List<? super Applemeans a list of some unknown supertype ofApple. In such a variable you can put aList<Apple>,List<Fruit>(assumingFruitis a supertype ofApple) orList<Object>, for example.This is exactly the meaning of supertype:
List<? super Apple>is more general thanList<Apple>.List<Apple>you can put apples, and nothing else. Everything you get out of the list is an apple.List<? super Apple>you can put apples (nothing else, since you don’t know the exact type). Everything you get out of the list is an object, but we don’t know what kind of object (since it could be aList<Object>, for example).If we use
List<? extends Apple>, it is similar: It means a list of some unknown subtype ofApple. This might be aList<Apple>,List<GoldenDelicious>,List<GrannySmith>,List<Jonagold>and so on.List<Apple>you can put apples (all types of apples), and everything you get out of it is an apple.List<? extends Apple>you can’t put anything – as you don’t know which subtype of Apple was actually used. But everything we get out of this is in fact an apple.We can do all things and some more with a
List<Apple>than withList<? super Apple>or withList<? extends Apple>– e.g. it is a subtype of both of these wildcard types.(The same applies to all generic types and their wildcard variants, it is just more easy to see for lists and similar container types.)