Reputation: 23301
I have a class that has a member defined as:
Map<Class<? extends Model>, List<? extends Model>> mockStore;
In this class I have a method:
protected <T extends Model> void insertMockStore(T obj)
{
mockStore.get(obj.getClass()).add(obj);
}
But this method gives a compilation error:
The method add(capture#8-of ? extends Model) in the type List is not applicable for the arguments (T)
I don't understand this error because T is defined as extending Model, so why would it say T is not applicable?
Upvotes: 3
Views: 698
Reputation: 49744
Your member declaration says that the values of mockStore
will be lists containing an unspecified subclass* of Model
.
The insertMockStore
method does similarly but there's nothing guaranteeing that the subclass of Model
passed to insertMockStore
will be the same as the lists.
What you should do instead is declare mockStore
like this:
Map<Class<? extends Model>, List<Model>> mockStore;
An easy-to-remember rule of thumb here is the "PECS rule": producer extends, consumer super. This means that if your member has a collection with type parameter Foo
, all producer type methods (ones that insert into your collection) will need T extends Foo
and all consumer type methods (those that return values from the collection) should have T super Foo
.
*As always with generics, in "subclass" we include the class itself.
Upvotes: 6
Reputation: 533530
Your mockStore
has List<? extends Model>
values so it doesn't know if you can add a T
to it.
A simpler solution is to simplify your declaration.
private final Map<Class, List> mockStore;
@SuppressWarning("unchecked")
protected void insertMockStore(Model obj) {
mockStore.get(obj.getClass()).add(obj);
}
Upvotes: 1