Java-8中“function接口”的精确定义
最近我开始研究Java 8,我不能完全理解Java实现lambdaexpression式所必需的“function接口”的概念。 在Java中有一个非常全面的 lambda函数的指南 ,但是我陷入了定义函数接口概念的章节 。 定义如下:
更确切地说,一个function接口被定义为只有一个抽象方法的任何接口。
然后他继续举例,其中一个是“比较器”界面:
public interface Comparator {int compare(T o1,T o2); boolean equals(Object obj); }
我能够testing,我可以使用lambda函数来代替Comparator参数,它的工作原理(即Collections.sort(list, (a, b) -> ab)
)。
但是在Comparator接口中,compare()和equals()方法都是抽象的,这意味着它有两个抽象方法 。 那么如果定义需要一个接口只有一个抽象方法 ,那么这怎么可能呢? 我在这里错过了什么?
从您链接到的同一页面 :
接口比较器是function性的,因为尽pipe它声明了两个抽象方法,其中一个equals方法具有与Object中的公共方法相对应的签名。 接口总是声明与Object的公共方法相对应的抽象方法,但是它们通常是隐含的。 无论是隐式还是显式声明,这些方法都不包括在内。
我不能说得更好。
编辑:更新到这个页面的最新文本,根据Maurice的评论(谢谢!)
问:但是在Comparator接口中,compare()和equals()方法都是抽象的,这意味着它有两个抽象方法。 那么如果定义需要一个接口只有一个抽象方法,那么这怎么可能呢? 我在这里错过了什么?
一个。
function接口可以指定任何由Object定义的公共方法,如equals(),而不影响其“function接口”状态。 公共对象方法被认为是一个function接口的隐式成员,因为它们是由一个function接口的实例自动实现的。
另一个解释在@FunctionalInterface页面中给出:
从概念上讲,一个function接口只有一个抽象方法。 由于默认方法有一个实现,它们不是抽象的。 如果一个接口声明一个抽象方法覆盖
java.lang.Object
的公共方法之一,那么也不会计入接口的抽象方法计数,因为接口的任何实现都将具有java.lang.Object
或其他地方的实现。
您可以使用@FunctionalInterface
testing哪个接口是正确的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()
? algorithm上,这是微不足道的。
我认为在接口中声明的所有方法都是抽象的(即没有默认实现)。 但也许我错过了一些东西。