I'm little confused about how the generics works? I'm learning about function API in java and there I just test Function interface and got confused about compose method that how the generics is working in compose method.
Reading the generics on the java official tutorial website I realize that if we have any generic type in the method return or parameters we have to declare that type in the signature of method as explained below.
Here is the method I read in official docs tutorial.
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
    return p1.getKey().equals(p2.getKey()) &&
           p1.getValue().equals(p2.getValue());
}
Above method have two types, K, V which are declared in the signature after the static keyword as  but when I read java Function API there is one method called compose and the signature of the compose is as
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
}
1) The first question where is the T & R declared? which are being used in the return type and in the parameter. Or my understanding is wrong?
Then I read more in generics tutorials and then I try to understand the concept of super and extends in generics and read here then I test compose method more and then confused again about how the super and extends works in the compose method?
public static void main(String... args){
    Function<Integer, String> one = (i) -> i.toString();
    Function<String, Integer> two = (i) -> Integer.parseInt(i);
    one.compose(two);
}
As above I have declared two Function with lamdas. One is having Integer input and String output the other one is reversed from it.
2) The second question is that how Integer and String are related to extends and super? There is no relation between String and Integer class no one is extending each other then how it is working?
I tried my best to explain my question/problem. Let me know what you didn't understand I will try again.
 
     
     
    