【问题标题】:Why does using a base class for a method reference cause a compiler error为什么使用基类作为方法引用会导致编译器错误
【发布时间】:2018-11-19 15:18:04
【问题描述】:

我正在使用Comparators 对流进行排序,但遇到了一个我不理解的编译器错误。

假设我有以下课程:

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

我正在创建两个比较器以按日期对Subs 进行排序,一个按自然顺序,一个按相反顺序。以下代码编译:

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

为什么会出现这些编译器错误?为什么在从fwd 构建rev2 时可以有效地规避它们?

(如果相关,我正在使用 Eclipse Oxygen.3a (4.7.3) 和 Java v1.8.0_162。)

【问题讨论】:

  • 您可能只需要在comparing 方法上显式声明泛型类型参数。
  • @aominè 我不相信这是您所指问题的重复。在那个问题中,没有父/子类关系。此外,在那个问题中,使用方法引用进行编译,而在我的问题中则没有。你能解释一下为什么你认为另一个问题的答案可以解释我的情况吗?
  • @dave 帖子重新打开。
  • 你的解释中Competition的类在哪里?
  • @YassinHajaj 对Competition 的引用是一个错误,来自我的实际问题,而不是我的问题中的mcve。我已经编辑了我的问题来解决这个问题。

标签: java compiler-errors java-stream comparator


【解决方案1】:

正如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());

【讨论】:

  • 感谢您的解释。我测试了您的第一个解决方案,它解决了表明您的假设重新类型推断是正确的错误。我已经发现了您的第二个解决方案,并保留了它,因为它看起来更清晰(并且更容易看到)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-22
  • 2020-04-26
  • 2016-05-13
  • 2019-11-18
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
相关资源
最近更新 更多