Java 8中“function接口”的精确定义

最近我开始研究Java 8,我不能完全理解Java实现lambdaexpression式所必需的“function接口”的概念。 在Java中有一个非常全面的 lambda函数的指南 ,但是我陷入了定义函数接口概念的章节 。 定义如下:

更确切地说,一个function接口被定义为只有一个抽象方法的任何接口。

然后他继续举例,其中一个是Comparator接口:

 public interface Comparator { int compare(T o1, T o2); boolean equals(Object obj); } 

我能够测试,我可以使用lambda函数来代替Comparator参数,它的工作原理(即Collections.sort(list, (a, b) -> ab) )。

但是在Comparator接口中, compareequals方法都是抽象的,这意味着它有两个抽象方法 。 那么如果定义需要一个接口只有一个抽象方法 ,那么这怎么可能呢? 我在这里错过了什么?

从您链接到的同一页面 :

接口比较器是function性的,因为尽管它声明了两个抽象方法,其中一个equals方法具有与Object中的公共方法相对应的签名。 接口总是声明与Object的公共方法相对应的抽象方法,但是它们通常是隐含的。 无论是隐式还是显式声明,这些方法都不包括在内。

我不能说得更好。

编辑:更新到这个页面的最新文本,根据Maurice的评论(谢谢!)

问:但在Comparator接口中,compare()和equals()方法都是抽象的,这意味着它有两个抽象方法。 那么如果定义需要一个接口只有一个抽象方法,那么这怎么可能呢? 我在这里错过了什么?

一个。

function接口可以指定任何由Object定义的公共方法,如equals(),而不影响其“function接口”状态。 公共对象方法被认为是一个function接口的隐式成员,因为它们是由一个function接口的实例自动实现的。

另一个解释在@FunctionalInterface页面中给出:

从概念上讲,一个function接口只有一个抽象方法。 由于默认方法有一个实现,它们不是抽象的。 如果一个接口声明一个抽象方法覆盖java.lang.Object的公共方法之一,那么也不会计入接口的抽象方法计数,因为接口的任何实现都将具有java.lang.Object或其他地方的实现。

您可以使用@FunctionalInterface测试哪个接口是正确的function接口

例如:

  • 这工作

     @FunctionalInterface public interface FunctionalInterf { void m(); boolean equals(Object o); } 
  • 这会产生一个错误:

     @FunctionalInterface public interface FunctionalInterf { void m(); boolean equals(); } 

    在FunctionalInterf接口中find多个非重写抽象方法

Java文档说:

请注意,不重写Object.equals(Object)总是安全的。 但是,在某些情况下,通过允许程序确定两个不同的比较器强加相同的顺序,覆盖此方法可能会提高性能。

比较器是特殊的吗? 也许,即使它是一个接口,有一个默认实现的equals()调用compare() ? 算法上,这是微不足道的。

我认为在接口中声明的所有方法都是抽象的(即没有默认实现)。 但也许我错过了一些东西。

定义:

如果一个接口只包含一个抽象方法,那么这种types的接口称为function接口。

用法:

  1. 一旦我们编写Lambdaexpression式“ – >”来调用它的function,那么在这种情况下,我们需要function接口。
  2. 我们可以使用Functional Interface引用来引用Lambdaexpression式。
  3. 在函数内部我们可以有一个抽象方法和n个默认/静态方法。

关于inheritance的function接口:

如果一个接口扩展了Functional接口,并且子接口不包含任何抽象方法,那么子接口也被认为是Functional Interface。

function性接口对于Java来说并不陌生,它已被用于以下接口API:

  1. Runnable:只包含run()方法。
  2. Callable:只包含call()方法。
  3. Comparable:只包含compareTo()方法。