I'd approach this by asking, which signature would make most sense? There are three options:
Function<? extends T, ? extends U>
Function<T, ? extends U>
Function<? super T, ? extends U>
First of all, ? extends T
does not include T
. So you could not pass Function<T, U>
to CompletionStage<T>
which would have been unexpected. So ? extends T
is not the best choice.
This leaves us with simply T
or ? super T
.
Simply T
would work for Function<T, U>
, just as ? super T
. But which is better? ? super T
would allow you to apply functions with arguments which are T
or superclasses of T
. This is much more flexible compared to simply T
since you could use more generic functions. For instance, you could do CompletionStage<Integer>.thenApply(Function<Number, String>)
which would not be possible with simple T
. ? super T
also does not seem to have any drawbacks, at least I don't see any.
So from my point of view, ? super T
is clearly a better choice.