Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayList <? super Number> and Double [duplicate]

Tags:

java

generics

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??

    }
like image 619
JohnJohnGa Avatar asked Nov 10 '11 16:11

JohnJohnGa


1 Answers

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.

like image 80
Jon Skeet Avatar answered Oct 29 '22 22:10

Jon Skeet