假设将Comparator.comparing源代码从
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}至
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<T, U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}我们有下面的课程
class PhysicalObject {
double weight;
public Double getWeight(){
return weight;
}
}
class Car extends PhysicalObject {}以下状态不能编译
Function<PhysicalObject, Double> weight = p->p.getWeight();
Comparator<Car> c = HypotheticComparators.comparing(weight);
在编译Comparator<Car> c3_1 = HypotheticComparators.comparing(PhysicalObject::getWeight);时
我知道第一条语句无法编译是因为修改后的比较函数没有有界通配符(? super T),但是为什么第二条语句可以编译而没有任何问题呢?
发布于 2018-03-08 07:04:20
将comparing定义为:
Comparator<T> comparing(Function<T, U> keyExtractor) // abbreviated声明:
Comparator<Car> c = comparing(weight);需要参数为Function<Car, ?>,但weight是Function<PhysicalObject, Double>,因此会出现编译错误。
然而,当你在做
Comparator<Car> c3_1 = comparing(PhysicalObject::getWeight);Function<Car, ?>方法? apply(Car t)由超类PhysicalObject的Double getWeight()充分实现,因为t->getWeight()是对该方法的调用。
PhysicalObject::getWeight方法引用类似于下面的lambda:
Comparator<Car> c3_1 = comparing((Car t) -> {
PhysicalObject p = t;
return p.getWeight(); // call PhysicalObject::getWeight
});或下面的匿名类:
Comparator<Car> c3_1 = comparing(new Function<Car, Double>() {
@Override
public Double apply(Car t) {
PhysicalObject p = t;
return p.getWeight();
}
});方法引用中允许从Car到PhysicalObject的扩大转换。
发布于 2018-03-08 06:49:45
根据JLS (§18.2.1: Expression Compatibility Constraints),这是由于类型推断章节中精确方法引用的缩减阶段,如下图所示。

从本质上讲,编译器能够推断出,因为Car扩展了PhysicalObject,所以它应该能够使用Function<Car, Double>定义Comparator<Car>。
但是,显式传递Function<PhysicalObject, Double>来创建Comparator<Car>将不起作用,因为没有足够的信息可供编译器正确推断。
https://stackoverflow.com/questions/49162228
复制相似问题