The file GenericInterface.java:
import java.lang.Comparable;
import java.util.function.Function;
public class GenericInterface {
}
interface Comparator<T> {
int compare(T o1, T o2);
static <T, U extends Comparable<?>> //comment out this line
//static <T, U extends Comparable<? super U>> //and uncomment this line to pass compiling
Comparator<T> Comparing(Function<? super T, ? extends U> mapper) {
return new Comparator<T>() {
@Override
public int compare(T o1, T o2) {
return mapper.apply(o1).compareTo(mapper.apply(o2));
}
};
}
//...
}
Then compile it with JDK 1.8 by javac GenericInterface.java -Xdiags:verbose
, resulting the following error:
GenericInterface.java:16: error: method compareTo in interface
Comparable<T#2> cannot be applied to given types;
return mapper.apply(o1).compareTo(mapper.apply(o2));
^
required: CAP#1
found: CAP#2
reason: argument mismatch; U cannot be converted to CAP#1
where U,T#1,T#2 are type-variables:
U extends Comparable<?> declared in method <T#1,U>Comparing(Function<? super T#1,? extends U>)
T#1 extends Object declared in method <T#1,U>Comparing(Function<? super T#1,? extends U>)
T#2 extends Object declared in interface Comparable
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends U from capture of ? extends U
1 error
I can pass compiling by changing this line
static <T, U extends Comparable<?>>
to this
static <T, U extends Comparable<? super U>>
But I don't know why:
CAP#1 extends Object from capture of ?
CAP#2 extends U from capture of ? extends U
Shouldn't CAP#1 and CAP#2 be U extends Comparable<?>
? Could anyone tell me how Java captures type variables in a generic method of a generic interface like the one above?