Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java generics , clarification on extends and super [duplicate]

Tags:

java

generics

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 ??

like image 223
user3385957 Avatar asked Nov 18 '25 09:11

user3385957


1 Answers

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.

like image 111
lexicore Avatar answered Nov 20 '25 21:11

lexicore