当前位置: 首页 > 知识库问答 >
问题:

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

左劲
2023-03-14

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

假设我有以下课程:

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

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

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构建rev 2时有效地规避它们?

(如果相关的话,我正在使用Eclipse Oxygen.3a(4.7.3)和Java v1.8.0\u 162。)

共有1个答案

郎雪风
2023-03-14

正如此答案所述,目标键入会因调用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<Sub> rev1 =
    Comparator.comparing(Base::getStartDate, Comparator.reverseOrder());
 类似资料:
  • 问题内容: 遇到一个错误地使用 而不是 在其代码中的人,它没有显示为编译错误。 是因为 是相同的 ? 问题答案: 没有编译错误,因为它是有效的(尽管相当无用) 一元运算符 ,其使用方式与以下方式相同: Java语言规范中的相关部分是Unary Plus运算符+(第15.15.3节) 。它指定调用一元运算会导致操作数的一元数值提升(第5.6.1节)。这意味着: * 如果操作数是编译时类型的,,,或,

  • 我很难理解为什么要编译以下代码: 我可以理解为什么第一个赋值是有效的-

  • 根据SQL字符串组合文档,我想在postgresql数据库中执行DELETE语句: 这将导致以下错误: 另一方面,类似的execute工作正常: 我真的看不出有什么区别...

  • 对于我的Java类,要求我们在working For语句中添加分号,并解释为什么输出是这样的。我不明白为什么添加分号会产生错误的树类型错误,导致代码无法编译。代码下面是输出;我还向any标记添加了反斜杠,因为它不会以其他方式显示。那么,为什么for语句后面的分号会导致这样的错误呢?提前谢谢。 运行时间:

  • 为什么这不能用gcc48和clang32编译? GCC错误: 叮当声错误: 编辑-解决方案 我已经接受了查尔斯·萨尔维亚的回答,但出于实际原因,我无法使用提出的变通方法(专门研究N)。我找到了其他适合我的解决办法。如果依赖于T,则启用_:

  • 在新的C 20标准中,CpPrerence表示: 在包含初始值设定项的完整表达式结束之前,存在使用直接初始化语法(括号)而不是列表初始化语法(大括号)初始化的聚合的引用元素中与引用的临时绑定。例子: 注意:我使用的是GCC,因为这是唯一支持此功能的编译器。阅读本文并了解引用是多态的,我决定创建一个简单的类: 因此,以下代码起作用: 我遇到的问题是更改多态对象的值(不是obj的值,而是多态对象本身的