I went through these topics
However, I still seem to be kind of lost with super
keyword:
When we declare a collection like that:
List<? super Number> list = null; list.add(new Integer(0)); // this compiles list.add(new Object()); // this doesn't compile
shouldn't it be the opposite - we have a list that contains some objects (of unknown type) which are parents of Number
. So Object
should fit (since it is the parent of Number
), and Integer
shouldn't. The opposite is the case for some reason.
Provided we have the following code
static void test(List<? super Number> param) { param.add(new Integer(2)); } public static void main(String[] args) { List<String> sList = new ArrayList<String>(); test(sList); // will never compile, however... }
It is impossible to compile the above code (and my sanity suggests that this is the right behaviour), but the basic logic could prove the opposite:
String is Object, Object is superclass of Number. So String should work.
I know this is crazy but isn't this the reason why they didn't allow <S super T>
constructs? If yes, then why <? super T>
is allowed?
Could someone help me restore the missing part of this logic chain?
super is a lower bound, and extends is an upper bound.
super T denotes an unknown type that is a supertype of T (or T itself; remember that the supertype relation is reflexive). It is the dual of the bounded wildcards we've been using, where we use ? extends T to denote an unknown type that is a subtype of T .
The super() in Java is a reference variable that is used to refer parent class constructors. super can be used to call parent class' variables and methods. super() can be used to call parent class' constructors only.
The polymorphism applies only to the 'base' type (type of the collection class) and NOT to the generics type.
The bounded wildcard in List<? super Number>
can capture Number
and any of its supertypes. Since Number extends Object implements Serializable
, this means that the only types that are currently capture-convertible by List<? super Number>
are:
List<Number>
List<Object>
List<Serializable>
Note that you can add(Integer.valueOf(0))
to any of the above types. however, you CAN'T add(new Object())
to a List<Number>
or a List<Serializable>
, since that violates the generic type safety rule.
Hence it is NOT true that you can add
any supertype of Number
to a List<? super Number>
; that's simply not how bounded wildcard and capture conversion work. You don't declare a List<? super Number>
because you may want to add an Object
to it (you can't!); you do because you want to add Number
objects to it (i.e. it's a "consumer" of Number
), and simply a List<Number>
is too restrictive.
extends
, consumer-super
new Integer(0)
vs valueOf
, etcFor the first part List<Number>
fits in List<? super Number>
but you can't add an Object
to a List<Number>
. That's why you can't add an Object
to List<? super Number>
.
On the other hand you can add every subclass of Number
(Number
included) to your list.
For the second part, String
is an Object
, but String
isn't a superclass of Number
.
If it worked like this, as every class is a subclass of Object
, super
would have no meaning.
List<? super Number>
:List<Object>
List<Object>
will workObject
fits in <? super Number>
Number
to a List<Object>
String
in it the only thing you're sure of is that you can add any subclass of Number
.List<Number>
: List<Number>
will workNumber
fits in <? super Number>
Number
to a List<Number>
List<Integer>
(or any subclass of Number
): List<Integer>
won't workNumber
so it is exactly what we want to avoidInteger
fits in a Number
you wouldn't be abble to add any subclass of Number
in a List<Integer>
(for example a Float
)super
doesn't mean a subclass.List<String>
(or any class not extending Number
nor in the "super hierarchy" of Number
(ie. Number
and Object
) : List<String>
won't workString
doesn't fit in Number
"super hierarchy"String
fits in Object
(which is a super class of Number
) you woudln't be sure to be able to add a Number
to a List
that contain any subclass from one of the super classes of Number
)super
doesn't mean any subclass of one of the super classes, it only means one of the super classes.How does it work ?
You could say that as long as you can add any subclass of Number
with your typed List
, it respects the super
keyword.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With