【问题标题】:Why @FunctionalInterface annotation is added to Comparator interface in Java 8?为什么在 Java 8 的 Comparator 接口中添加了 @FunctionalInterface 注解?
【发布时间】:2016-01-17 18:47:41
【问题描述】:

我知道使用 Java 8 的 default 关键字添加了一堆带主体的方法。我的问题是这个注释在哪里有用?我看到只有一个抽象方法允许添加这样的注释。但是 Comparator 有两个抽象方法:

  • int compare(T o1, T o2);
  • boolean equals(Object obj);

另外,请解释一下这个注解的用途?我看到它是一个运行时注解,那么它的用途是什么?

【问题讨论】:

  • 我想这有你的答案:stackoverflow.com/questions/28166187/…
  • @coolguy:区别在于Comparator实际上声明了equals,但没有声明hashCode。所以equals是接口定义的一部分,列在JavaDoc等中; hashCode 不是,虽然Comparator实现当然会从Object 继承并得到它。
  • 声明equals方法的意义何在?他们本可以像哈希码方法一样离开它吗?
  • @user2296988 可能的原因之一是在 Comparator 的上下文中提供该方法的更具体的文档。可能类似于“为什么ArrayList已经扩展了AbstractList,为什么还要实现List?”。

标签: java java-8


【解决方案1】:

来自documentation of FunctionalInterface

如果一个接口声明了一个覆盖java.lang.Object 的公共方法之一的抽象方法,这也不会计入接口的抽象方法计数,因为该接口的任何实现都将具有来自java.lang.Object 或其他地方的实现。

由于equals 来自java.lang.Object,因此不计算在内。与FunctionInterface相关的是compare方法。

【讨论】:

  • 谢谢。你能解释一下这个注释的用途吗?我看到它是一个运行时注解,那么除了将它与 instanceof 运算符一起使用之外,它还有什么用途?
  • @user2296988 它主要用于文档和静态分析工具,例如建议 IDE 应该在哪里建议将匿名类更改为 lambda。
  • 更准确地说,它的目的是捕捉设计意图。这里的具体设计意图是这个接口描述了一个独立的行为(计算一个函数,分配一个资源等),因此作为 lambdas 和方法 refs 的目标类型是明智的。
  • “与 instanceof 运算符一起使用之外的其他用途”是一个奇怪的前提。将 instanceof 运算符与注释一起使用是相当不典型的。一个典型的用例宁愿看起来像Foo.class.hasAnnotation(FunctionalInterface.class)
【解决方案2】:

这很有用,因为如果你添加它并且你在接口中有多个方法,你会得到一个编译错误。 @FunctionalInterfaces 用于让 Java 知道这段代码可能会被 lambda 表达式替换,因为每个 lambda 都是一些 @FunctionalInterface 的实现。它可以帮助编译器知道方法签名是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多