1

In the following code snippet:

        List<Integer> ints = new ArrayList<Integer>();
        ints.add(1);
        ints.add(2);
        List<? extends Number> nums1 = ints;
        ints.add(3);
        ints.add(4);
        System.out.println("nums1 : " + nums1);
        List<? super Number> nums2 = (List<? super Number>) nums1;
        nums2.add(5.381);
        nums2.add(6);
        //ints.add(7.61762); // compilation error
        System.out.println("nums2 : " + nums2);
        System.out.println("ints : " + ints);

The List of Integer (ints here) is printed as : ints : [1, 2, 3, 4, 5.381, 6] So it seems that something is wrong here ?

Actual O/P :

nums1 : [1, 2, 3, 4]

nums2 : [1, 2, 3, 4, 5.381, 6]

ints : [1, 2, 3, 4, 5.381, 6] <-- Why 5.381 is fine in List

ARC
  • 9
  • 3

2 Answers2

1

List<? extends Number>:

List<? extends Number> eExtend = new ArrayList<Number>();  
List<? extends Number> eExtend = new ArrayList<Integer>();
List<? extends Number> eExtend = new ArrayList<Double>(); 

In above code sample you can't add an Integer because eExtend could be pointing at a List<Double>. And you can't add a Double because eExtend could be pointing at a List<Integer>. Also you can't add a Number because eExtend could be pointing at a List<Integer>.

List<? super Number>:

List<? super Integer> eSuper = new ArrayList<Integer>(); 
List<? super Integer> eSuper = new ArrayList<Number>();
List<? super Integer> eSuper = new ArrayList<Object>();

In above code sample you can add an Integer because an Integer is allowed in any of above lists. And you can add an instance of a subclass of Integer because an instance of a subclass of Integer is allowed in any of the above lists. But you can't add a Double because eSuper could be pointing at a ArrayList<Integer>. Also you can't add a Number because eSuper could be pointing at a ArrayList<Integer>. You can't add a Object because eSuper could be pointing at a ArrayList<Integer>.

List<? super Number> eSuper = new ArrayList<Number>();

You can add an instance of a subclass of Number because an instance of a subclass of Number allowed here. (Double,Integer)

Madushan Perera
  • 2,568
  • 2
  • 17
  • 36
  • So you mean when ints list is seen by System.out.println, its now seeing it as a list of Number instead of list of Integer and thus printing the number with decimal point. I can understand that its inserting a Double due to some reasoning, but not getting why the entire code further treats this as List of Number? – ARC Dec 05 '15 at 04:22
  • Can you run the example once and see this? – ARC Dec 05 '15 at 04:23
  • `ints.add(7.61762);` will give an error because you are trying to add a double value to `List ints`. But `nums2` can have double values because `Double` and `Integer` are sub types of `Number` You should keep in mind that `list.add()` method only allows same type or sub type objects every time. – Madushan Perera Dec 05 '15 at 05:01
  • As I have mentioned in my answer If you change your code to `List super Integer> nums2 = (List super Number>)nums1;` and try to add double value to your list `nums2.add(5.381);` again gives you an error. – Madushan Perera Dec 05 '15 at 05:07
  • `List super Integer> eSuper = new ArrayList();` "you can't add a Double because `eSuper` could be pointing at a `ArrayList`." – Madushan Perera Dec 05 '15 at 05:08
  • I have no problems in nums2.add(7.61762); this is perfectly fine. Whats bothering me is, why System.out.println("ints : " + ints); is printing ints : [1, 2, 3, 4, 5.381, 6], why its not printing ints : [1, 2, 3, 4, 5, 6] ? – ARC Dec 05 '15 at 05:26
  • When u do the following: System.out.print("looped ints : "); for(int i : ints) { System.out.print(i); } System.out.print("\n"); it will give runtime ClassCastException:java.lang.Double cannot be cast to java.lang.Integer So it seems that we are keeping a Double inside a list of integers. I think this should not be allowed, its a flawed implementation of generics. – ARC Dec 05 '15 at 05:30
0

That output is correct because at runtime type erasure will occur.

you've created 3 references List<Integer> ints,List<? extends Number> nums1 and List<? super Number> nums2 (mind the word reference) and one object new ArrayList<Integer>();.

Now remember that at runtime there is no ArrayList<Integer>() , the type will be erased and you get a ArrayList which can hold anything .Therefore your list end up containing Integer and double.

Ramanlfc
  • 8,283
  • 1
  • 18
  • 24