Reputation: 32261
Take a look at the next code:
ArrayList<? extends Object> list = new ArrayList<Object>();
list.add(new Object());
It does not compile. The question is why?
Upvotes: 2
Views: 103
Reputation: 200206
ArrayList<? extends Object>
is the same as just
ArrayList<?>
and you can assign any ArrayList
to a variable of this type. For example,
ArrayList<? extends Object> list = new ArrayList<String>();
is legal. Clearly, the language semantics will not let you add an Object
to such a list. In fact, they won't let you add anything at all to it, except null
, or something which you directly retrieved from the list.
As noted by Lukas in the comment, it is far from trivial to even add the list's own item back to it: you need a helper method to capture the wildcard into a named type.
public static void main(String[] args) {
ArrayList<? extends Object> list = new ArrayList<String>();
addOwn(list);
}
static <T> void addOwn(List<T> l) { l.add(l.get(0)); }
Upvotes: 6
Reputation: 172528
I think the reason is because Generic types are not polymorphic. When you use wildcards ?
with extends you cant add anything in the collection except null.
Here is an example to what will happen if that is allowed:
Class Car{
}
class A extends Car {
}
class B extends Car{
}
Now you have List<? extends Car>
public void someMethod(List<? extends Car> list){
list.add(new A()); //this is not valid
}
Also you may invoke the method like this:
List<B> someList = new Array:list<B>();
somemethod(someList);
Upvotes: 2
Reputation: 347
The problem is that Foo extends Object
does not mean Collection<Foo>
can be treated as a subtype of Collection<Object>
. This is simply because the former class does not permit you to do everything the latter does; for instance, you cannot add an Object
to a Collection<Foo>
. Using generics instead of some concrete class Foo
doesn't change this.
Upvotes: 2