From http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ103:
A wildcard with a lower bound looks like " ? super Type " and stands for the family of all types that are supertypes of Type , type Type being included. Type is called the lower bound .
So why
ArrayList<? super Number> psupn1 = new ArrayList<Number>();
psupn1.add(new Double(2));
compiled?
Double is not supertype of Number but subclass of Number...
Edit 1:
ArrayList<? super Number> pextn1 = new ArrayList<Number>();
psupn1.add(new Integer(2));
psupn1.add(new Double(2));
psupn1.add(new Float(2));
for(Number n : psupn1){ // [Invalid] Number should be change to
// Object even if I can only add subtype of Number??
}
You can add a Double
to that, because whatever the type parameter E
is, it's guaranteed to be either Number
or a supertype... which means you can definitely convert from Double
to E
. You wouldn't be able to do:
Number x = psupn1.get(0);
though.
Think about it, and try to create lists which would logically break this. For example, you can't use:
// Invalid
ArrayList<? super Number> psupn1 = new ArrayList<Integer>();
psupn1.add(new Double(2));
because Integer
isn't either Number
or a supertype - it's a subclass. You can write:
// Valid
ArrayList<? extends Number> psupn1 = new ArrayList<Integer>();
... because that's the other way round. At that point you can write:
Number x = psupn1.get(0);
because any element in the list is guaranteed to be convertible to Number
. It's all about which way the conversions are required - to the generic type parameter or from it.
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