代码之家  ›  专栏  ›  技术社区  ›  dave

为什么对方法引用使用基类会导致编译器错误

  •  4
  • dave  · 技术社区  · 7 年前

    我在用 Comparator 我遇到了一个编译器错误,我不明白。

    假设我有以下课程:

    class Base {
        private LocalDate date;
        public LocalDate getDate() { return date; }
        ...
    }
    class Sub extends Base { ... }
    

    我正在创建两个比较器来排序 Sub 一个按自然顺序,一个按相反顺序。以下代码编译:

    Comparator<Sub> fwd = Comparator.comparing(Sub::getStartDate);
    Comparator<Sub> rev1 = Comparator.comparing(Sub::getStartDate).reversed();
    Comparator<Sub> rev2 = fwd.reversed();
    

    意识到这一点 getDate() 定义于 Base ,我想我应该试试以下方法:

    Comparator<Sub> fwd = Comparator.comparing(Base::getStartDate);
    Comparator<Sub> rev1 = Comparator.comparing(Base::getStartDate).reversed();  // Compiler error
    Comparator<Sub> rev2 = fwd.reversed();  // OK
    

    令人惊讶的是(对我来说),代码 rev2 编译正常,而 rev1 产生以下错误:

    Cannot infer type argument(s) for <T, U> comparing(Function<? super T, ? extends U>)
    The type Base does not define getStartDate(Object) that is applicable here
    

    为什么会出现这些编译器错误?为什么我能有效地规避它们 Rev2 fwd ?

    (我使用Eclipse Office .3a(4.7.3)和JavaV1.80Y162,如果这是相关的。)

    1 回复  |  直到 7 年前
        1
  •  2
  •   Oleksandr Pyrohov Andreas    7 年前

    如前所述 answer ,目标类型被 reversed() :

    Comparator<Sub> rev1 =
        Comparator.comparing(Base::getStartDate)
                  .reversed(); // Compiler error - incompatible types
    

    在这种情况下,编译器似乎推断出以下类型参数:

    Comparator<Sub> rev1 =
        Comparator.<Base, LocalDate>comparing(Base::getStartDate)
                  .reversed(); // Compiler error - incompatible types
    

    为了消除错误,您可以显式地提供类型参数:

    Comparator<Sub> rev1 =
        Comparator.<Sub, LocalDate>comparing(Base::getStartDate)
                  .reversed(); // Okay, no problem
    

    或使用两个参数 Comparator.comparing() :

    Comparator<Sub> rev1 =
        Comparator.comparing(Base::getStartDate, Comparator.reverseOrder());