Why can't I add an item to the list of generalized generalizations?

I have a list with generic generics.

List<? extends Number> l = new ArrayList<>(); l.add(new Integer(3)); //ERROR l.add(new Double(3.3)); // ERROR 

I do not understand the problem, because Integer and Double extend Number.

+8
java
source share
5 answers

List<? extends Number> List<? extends Number> does not mean "a list that can contain all objects of subclasses of Number ", it means "a list parameterized for one particular class that extends Number ". This is not the content of the list itself that you define, it is that the parameterized type of the actual object list assigned to the variable may be (boy, this is harder to explain than it needs to be understood :))

So you can do:

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

If you need a list that can hold any object of the Number class or its subclasses, just do the following:

 List<Number> l = new ArrayList<>(); l.add(new Integer(33)); l.add(new Double(33.3d)); 

(Box of inserted values ​​is not needed, but there for an example ..)

+16
source share

Upper bounded and unlimited wildcard collections are immutable.

For example, you cannot do:

 List<? extends Number> myList = new ArrayList<Integer>(); myList.add(new Integer(3)); //will not compile 

This will not compile because java does not know what type of List List<? extends Number> List<? extends Number> is at compile time.

So, the example above at compile time myList could be List<Double> or List<Integer> or List any subclass of Number . And since you cannot add Double to the List<Integer> or vice versa, compilation failed.

+1
source share

Because List<? extends Number> List<? extends Number> means that your variable l contains a value of type List with an argument of type concrete (but unknown!), which extends Number .

You can add only null , because l can contain a List<MyClass> , for example, where MyClass is your class that extends Number , but not Integer , and not Double value can be dropped to MyClass .

0
source share

I will add another way to add Number subtypes to this list. i.e

 List<? super Number> l = new ArrayList<>(); l.add(new Integer(3)); //OK l.add(new Double(3.3)); //OK 

This is allowed because the list is parameterized like any unknown supertype of the Number class. therefore, the compiler resolves the well-known subtype of Number . ie Integer and Double types

0
source share

Yes in case

 List<? extends Number> 

this is just a link, maybe the actual object will be

 List<Integer> 

therefore, you should not be allowed to add a new Double (5.0) to the Integer list.

0
source share

All Articles