This code
static void writeTo(List<? super Apple> apples) {
apples.add(new Apple());
apples.add(new Jonathan());
}
The author of this code stated that
The argument apples is a List of some type that is the base type of Apple; thus you know that it is safe to add an Apple or a subtype of Apple. Since the lower bound is Apple,
Jonathan is a subclass of Apple.
But when I tried this
List<Jonathan> loj = new ArrayList<Jonathan>();
listSuper(loj);
It gave me this error
The method listSuper(List<? super Apple>) in the type Basket<T> is not applicable for the arguments (List<Jonathan>)
Where listSuper looks like this
static void listSuper (List<? super Apple> cont) {}
How does the two differ?
Also what confuses me on the first code that I posted is that
I thought ? super T means that any base type of T. but from the looks of it he added a subtype of T. I am confused.
List<? super Apple>means aListyou can add anAppleto (and sinceJonathanis anApple, you can putJonathans into aListof that type as well).It can be
List<Apple>,List<Fruit>orList<Object>, but notList<Jonathan>, since you cannot put arbitraryApples intoList<Jonathan>. As you can see, in this case?can be anAppleor any of its superclasses.List<? extends Apple>means aListyou can get anApplefrom. It can beList<Apple>orList<Jonathan>, but notList<Fruit>, sinceList<Fruit>is not guaranteed to contain onlyApples.This explanation is known as “producer –
extends, consumer –super” rule: if parameter acts as a consumer of elements, it should be declared withsuper, and vice versa.