1

Consider the following example,

List<? super Number> list1 = new ArrayList<>();
list1.add(10);
list1.add(10.10);
list1.add(20.20d);

and another list to which i assign list1

List<? super Integer> list = list1;
System.out.println(list.toString());

Now, when i print the list it contains double values also BUT the list is only supposed to hold Integer and anything above Integer.

If the above is fine then shouldn't the following compile as well ?

list.add(30.30);
Adithya
  • 2,597
  • 5
  • 28
  • 46
  • Possible duplicate of [Difference between super T> and extends T> in Java](https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java) – texasbruce Mar 18 '18 at 20:17
  • https://stackoverflow.com/a/4343547/1270003 This answer tells you that to write (add) to a list, you need to use `super`, while to read (toString), you need to declare it using `extends` (e.g. `list`), and that will give you a compiler warning. This is probably the unsafe downside of Java – texasbruce Mar 18 '18 at 20:25

1 Answers1

5

Everything makes sense if you consider the possible things you could assign to it.

List<? super Number> list1 = new ArrayList<Object>(); // works
List<? super Number> list1 = new ArrayList<Number>(); // works
List<? super Number> list1 = new ArrayList<Integer>(); // doesn't work

Anything that works on the right hand side will accept a Double.

List<? super Integer> list = new ArrayList<Object>(); // works
List<? super Integer> list = new ArrayList<Number>(); // works
List<? super Integer> list = new ArrayList<Integer>(); // works

Anything that you could assign to list1 you could also assign to list. So list = list1 works just fine. But not all of the things you could assign to list will accept a Double, so it doesn't compile.

Louis Wasserman
  • 172,699
  • 23
  • 307
  • 375
  • 1
    Your two blocks are the same, except the comment on line 3. Copy/paste error? Shouldn't second block be `List super Integer>`? – Andreas Mar 18 '18 at 20:13
  • Fixed the issue. – Louis Wasserman Mar 18 '18 at 20:46
  • Why doesn't the following work? `List super Number> list1 = new ArrayList(); // doesn't work` where as you can actually _add_ integers to it i.e. `list1.add(10)`. While initializing we are forcing the compiler to have only numbers but able to add integers. That means we can also _add_ objects down the hierarchy. – Adithya Mar 19 '18 at 06:34
  • All these questions arise due to _type inference_ i.e. one can declare `List super Number> list1 = new ArrayList<>();` – Adithya Mar 19 '18 at 06:50
  • Why would it? Integer isn't a super type of Number. – Louis Wasserman Mar 19 '18 at 16:04
  • Actually i should have asked _why shouldn't it_ :) ..what i mean to say is even if i define `List super Number> list = new ArrayList();` , you cannot add `list.add(new Object())`. Whole thing of using `super` is to add objects but in the downstream hierarchy i.e. in the above case, `Number` or any subclass of `Number`. – Adithya Mar 19 '18 at 16:43
  • 1
    A `List super Number>` can be anything from a `List` to a `List`. Only operations that work for all those possibilities are allowed. So anything you get out of the list could be an Object, but you can't add anything that isn't a Number. – Louis Wasserman Mar 19 '18 at 16:47