Function<? extends MyEntity,List> mapper;
This does not say "any subclass of MyEntity
can be passed to mapper
". It says "there exists some subclass of MyEntity
that can be passed to mapper
". It might be ClassExtendsMyEntity
, it might be MyEntity
itself, or it might be some crazy class that you've never even heard of.
Function<T, S>
provides one function: S apply(T arg)
. Since your argument type is ? extends MyEntity
, the only valid argument you can pass to mapper.apply
is a value which is of every subtype of MyEntity
at once, and there is no value that satisfies that condition.
Put more technically, the first argument of Function<T, S>
is, in principle, contravariant, so using the covariant ? extends T
annotation makes little sense on it.
Depending on what you want, there are two solutions. If your function works for any MyEntity
, then you should simply write Function<MyEntity, List>
and forgo the generics/wildcards altogether. On the other hand, if you want MyLibraryClass
to support only one subtype, but a subtype that you know about, then you need to make that a generic argument to MyLibraryClass
.
public class MyLibraryClass<T extends MyEntity> {
Function<? super T, List> mapper;
public MyLibraryClass(Function<? super T, List> mapper) {
...
}
public void aMethod(T e) {
mapper.apply(e);
}
}
Again, the first type argument of Function
is, in principle, contravariant, so we should use ? super T
to bound it by our type argument T
. That means that if I have a MyLibraryClass<ClassExtendsMyEntity>
, the function inside that might be a Function<ClassExtendsMyEntity, List>
, or a Function<MyEntity, List>
, or a Function<Object, List>
, since all of those support ClassExtendsMyEntity
arguments. For more on the reasoning behind that, see What is PECS.