Ilya Gazman
Ilya Gazman

Reputation: 32261

Java anonymous generic inheritance

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

Answers (3)

Marko Topolnik
Marko Topolnik

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

Rahul Tripathi
Rahul Tripathi

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

Jose Torres
Jose Torres

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

Related Questions