Question:
For example, this code:
public void add(List<? super Number> list) {
list.add(1D); // можно
list.add(new Object()); // нельзя
}
Why is that? After all, here – <? super Number>
– it says "any type that is a superclass for Number
". And the opposite works: "any type is a descendant of Number
". What's wrong? Why does it work the other way around?
Answer:
Yes, <? super Number>
really means "any type that is a superclass of Number
". Plus Number
itself.
For this reason, you can pass to a method like List<Object>
.
Since the type of the items in this list is "something superclassing Number
", you can add items to the list whose type is a child of Number
. For example Integer
:
public void add(List<? super Number> list)
{
list.add(1);
}
This is permissible, since you can add elements to the list whose type is a child of the list's element type. As is the case with a regular List<Number>
:
List<Number> list = new ArrayList<>();
list.add(1);
However, you cannot add new Object()
to the list, because there is no guarantee that you can store elements of type Object
: under ?
not only Object
can be "hidden", but also, for example, Number
itself. In the case of other classes ( ? super X
) that have intermediate classes between Object
and X
itself – also any intermediate class.
Since the true type of the elements of the list is unknown ( ?
), But any class has Object
as a superclass, then the element obtained from the list can be treated only as with Object
. Even with the unit that they just put in there.
In the case of <? extends Number>
means "any type that is a child of Number
". Plus Number
itself.
In this case, you can pass to a method like List<integer>
.
Since the element type is "something that is a child class of Number
", you cannot add anything to the list (except, perhaps, null
), because you do not know what exactly can be stored there.
But with the element obtained from the list, you can work as with Number
:
public static void add2(List<? extends Number> list)
{
int value = list.get(0).intValue();
}
Because whatever the elements in the list are, they are definitely from the child classes for Number
, which means they can work like Number
.