首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较器比较类型推断

比较器比较类型推断
EN

Stack Overflow用户
提问于 2018-03-08 06:26:12
回答 2查看 122关注 0票数 3

假设将Comparator.comparing源代码从

代码语言:javascript
复制
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));
}

代码语言:javascript
复制
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));
}

我们有下面的课程

代码语言:javascript
复制
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),但是为什么第二条语句可以编译而没有任何问题呢?

EN

回答 2

Stack Overflow用户

发布于 2018-03-08 07:04:20

comparing定义为:

代码语言:javascript
复制
Comparator<T> comparing(Function<T, U> keyExtractor) // abbreviated

声明:

代码语言:javascript
复制
Comparator<Car> c = comparing(weight);

需要参数为Function<Car, ?>,但weightFunction<PhysicalObject, Double>,因此会出现编译错误。

然而,当你在做

代码语言:javascript
复制
Comparator<Car> c3_1 = comparing(PhysicalObject::getWeight);

Function<Car, ?>方法? apply(Car t)由超类PhysicalObjectDouble getWeight()充分实现,因为t->getWeight()是对该方法的调用。

PhysicalObject::getWeight方法引用类似于下面的lambda:

代码语言:javascript
复制
Comparator<Car> c3_1 = comparing((Car t) -> {
    PhysicalObject p = t;
    return p.getWeight(); // call PhysicalObject::getWeight
});

或下面的匿名类:

代码语言:javascript
复制
Comparator<Car> c3_1 = comparing(new Function<Car, Double>() {
    @Override
    public Double apply(Car t) {
        PhysicalObject p = t;
        return p.getWeight();
    }
});

方法引用中允许从CarPhysicalObject的扩大转换。

票数 1
EN

Stack Overflow用户

发布于 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>将不起作用,因为没有足够的信息可供编译器正确推断。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49162228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档