Why do we need extends> and super> as method parameters
There is a function:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
It performs operations on the elements Stream
and returns Stream
with the resulting elements. We input the implementation of the functional interface, i.e. the method:
R apply(T t);
I'm doing it:
.map(User::getName)
That is, if I understand correctly, instead of T
, the type User
is "substituted", instead of R
, the type String
. Then explain why you need super
and extends
in the parameters at all?
I understand what super T
means: "T
or any of its superclasses", extends R
means "R
or any of its subclasses"?
What is the advantage of T
over super T
, where can it be used? With the usual method, everything is clear (we can pass an instance of any superclass as a parameter), but with a parameter of the type of the functional interface, not very much.
After all, we just pass the implementation with specific T(User)
and R(String)
, where can we use subclasses and superclasses?
2 answers
Java generics are built on the idea of PECS (production-extends; consumer-super), i.e. the producer defines the upper bounds, and the consumer defines the lower bounds.
Then in Function
where T
is the input data, and R
is the output data. It is often called mapping, since the input data is "mapped" to the output. Consider an example:
Function<String, Integer> fun = (str) ->
Integer.parseInt(str);
System.out.println(fun.apply("234"));
Here the input must be a string, and in the output we get an Integer. It turns out that in your version, the input was User
, and the output we need to get the user's name.
On the contrary, the advantage of the ? super T
type compared to T
is that in the first case, objects of different types can be sent to the input of the function, which are either T
or are a superclass of T
. That is, we can't say that the type of the parameter is T
. And also, we can't send objects that are inheritors of T
, as a function parameter. In the second case, the type T
is defined uniquely in the hierarchy, despite the fact that it is a generalized type, the heirs of {[1] are not accepted]} and he is not the heir of T
.