This is the class definition of CompletionStage
public interface CompletionStage<T> {
...
}
And this is the method thenApply
public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
My questions is: Why is it taking ? super T as the first argument of Function... shouldn't it be ? extends T since any subClass of T can be cast as T ? And any super class of T cannot be cast as T ??
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With