Sorry, I just realized my previous explanation was unrelated, please ignore.
Formal type | Upper bound | Lower bound |
---|
T | Object | Integer |
List<? super Number> | Object | Number |
List<? extends Number> | Number | CAP#1 |
In this table you can see that all bounds match with
T's bounds, except the lower bound of
List<? extends Number>. The lower bound of
List<? extends Number> is
CAP#1, which is another way of saying: We don't know what the lower bound is, but it could be
Integer, or
Double, or
Float or whatever else that extends
Number.
What causes this asymmetry between
super and
extends? The reason is because upper bounds have a single hard limit:
Object. No matter what the type is, everything is an
Object. The compiler can't perform the same trick with lower bounds, because when you have a
List<? extends Number>, there's no way of determining at compile time if its runtime type will be
List<Integer> or
List<Number> or
List<Double> or whatever.