A Wrap<ConcreteModel> can be assigned to a variable of type Wrap<? extends ModelObject> Wrap<? extends ModelObject> . But the matter is more complicated.
Suppose you have an ArrayList<Wrap<? extends ModelObject>> list ArrayList<Wrap<? extends ModelObject>> list . If you have this type, this means that you can add Wrap<ConcreteModel> to the list, but it also means that you can add Wrap<ModelObject> . In short, this means that you have a list that can contain a Wrap of everything that can be added to ModelObject .
On the other hand, having an ArrayList<Wrap<ConcreteModel>> list means that you can add a Wrap<ConcreteModel> , and a Wrap<ModelObject> cannot be added to it, because the list can only contain wrapped ConcreteModel s, but a wrapped one ModelObject not a wrapped ConcreteModel and cannot be distinguished from it.
This is exactly your case. You announced that your createMapper() method returns Transformer<Resource, Wrap<? extends ModelObject>> Transformer<Resource, Wrap<? extends ModelObject>> . This means that the second argument of the returned transformer must be any subclass of ModelObject , including ModelObject . On the contrary, you are trying to return Transformer<Resource, Wrap<ConcreteModel>> .
The compiler must enforce this because Transformer<F, T> can declare a method:
void myMethod(F fObject, T tObject);
If so, the myMethod method of myMethod object of type Transformer<Resource, Wrap<? extends ModelObject>> Transformer<Resource, Wrap<? extends ModelObject>> will accept an object of type ModelObject as the second argument. On the other hand, the same method in an object of type Transformer<Resource, Wrap<ConcreteModel>> cannot accept ModelObject as the second argument.
source share