Adding elements to a List? extends Number

3

Why can not I add elements to a list of type List<? extends Number> ?

For example:

public class GenClass{
  public static void main(String args[]){
    List<? extends Number> ml=new Vector<Integer>();

    ml.get(0); //ok
    ml.add(new Integer(7)); // erro de compilação
    ml.add(new Double(7d));// erro de compilação
    ml.add(new Number(7));// erro de compilação
    ml.add(new Object());// erro de compilação
  }
}
    
asked by anonymous 25.08.2017 / 20:22

1 answer

6

Adding elements to this list type is not possible because the wildcard declaration of List<? extends Number> ml means that the ml variable can contain any value of the Number family, rather than any value of a specific type. See the equivalent assignments below that would be allowed:

List<? extends Number> foo3 = new ArrayList<Number>;  // Number "extends" Number
List<? extends Number> foo3 = new ArrayList<Integer>; // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>;  // Double extends Number

Given this, the type of object you can add to the List foo3 that would be valid after any of the assignments above a ArrayList would bump into the problems below:

  • You can not add Integer because foo3 could be pointing to List<Double> .
  • You can not add Double because foo3 could be pointing to List<Integer> .
  • You can not add Number because foo3 could be pointing to List<Integer> .

Therefore:

  

You can not add any object to List<? extends T> because you can not guarantee that List is actually pointing to this type, so you can not guarantee that the object to be added is allowed in this list. The only "guarantee" you have is that you can only read this list and it will have a T subclass of T .

Reverse logic applies to the use of super , according to the following assignments, which are also valid:

List<? super Number> foo3 = new ArrayList<Number>; // Number é "superclasse" de Number
List<? super Number> foo3 = new ArrayList<Object>; // Object é "superclasse" de Number

About List<? super T> , you can reach the following conclusion:

  

You can not read the specific type T (for example Number ) from List<? super T> because you can not guarantee what List type is actually pointing to it. The only "guarantee" you have is that you are able to add a value of type T (or any subclass of T ) without violating the integrity of the list being pointed to.

The left declaration ( List<? extends Number> foo3 ) defines the type of data that can be assigned to your right ArrayLists ( = new ArrayList<Integer>(); ), not the type of data that can be added to the created list.

Translated and adapted from this SOEn response p>

References to reading:

26.08.2017 / 02:30