‘Comparable 应该是’function界面’吗?

function接口的定义是“function接口是一个只有一个抽象方法的接口(除了Object的方法),因此代表了一个单一的function契约。”

根据这个定义,Comparable绝对是一个function界面。

lambda表达式的定义是“lambda表达式就像一个方法:它提供了一个forms参数列表和一个正文 – 一个表达式或块 – 用这些参数表示。”

lambda表达式的评估产生function接口的实例。

因此,lambda表达式的目的是通过实现function接口的单个​​function来创建function接口的实例。

即。 允许使用单个函数创建实例。

让我们来看看Comparable,这个界面是否设计用作单一function? 即。 它是否仅用于创建具有此单一function的实例?

Comparable的文档以“此接口对每个实现它的类的对象强加一个总排序。这个顺序称为类的自然顺序,类的compareTo方法被称为它的自然比较方法。”

上面的句子清楚地表明Comparable并不是设计用作单个函数,而是总是由一个类实现,它通过添加这个单个函数对其实例具有自然顺序。

这意味着它不是设计为使用lambda表达式创建的。

关键是我们不会有任何仅仅是可比较的对象,它意味着要实现,因此用作类的附加function。

那么,Java语言中是否有一种方法可以防止为Comparable创建lambda表达式? 接口的设计者是否可以决定这个接口是由一个类实现的,而不是通过使用lambda表达式作为这个单一方法的实例而被哄骗?

仅仅因为接口恰好具有单个抽象方法,所以不应将其视为function接口。

可能是,如果Java提供像NotFunctional这样的注释,编译器可以检查该接口是否不用于创建lambda表达式,例如。

@NotFunctional public interface Comparable { public int compareTo(T t); } 

可以使用lambda表达式,其中需要具有单个抽象方法的接口的实例。 你写了,

仅仅因为接口恰好具有单个抽象方法,所以不应将其视为function接口。

这是完全正确的。 使用单个抽象方法是接口的结构属性,使其有资格使用lambda实现。 然而,一个接口是否有意义或在语义 是否合理用lambda实现是一个不同的故事。 后者是@FunctionalInterface注释的目的。 当它出现在接口上时,它表示该接口对于使用lambda实现有用的意图

值得注意的是, Comparable接口缺少@FunctionalInterface注释。

虽然使用lambda作为Comparable实现可能是荒谬的,但似乎没有任何理由创建一种机制来防止这种情况发生。 看起来这样做不会成为错误的根源,这是开发这种机制的一个很好的理由。 相比之下, @FunctionalInterface注释旨在引导程序员朝着正确的方向发展,而不是禁止可能存在错误但看起来并不真正有害的东西。

问题来自“方法”和“function”之间的细微差别。

函数的输出值仅取决于输入到该函数的参数。

但是,方法的输出取决于输入到函数的参数,但它也可能取决于对象的状态(实例变量)。

也就是说,任何函数都是方法,但并非所有方法都是函数。

例如,Comparator接口中的方法比较仅取决于其参数。 但是,Comparable接口中的方法compareTo取决于要比较的对象的状态,因此需要在类中实现。

因此,即使Comparable也有一个abstarct方法,从语义上讲它不应该被视为一个function接口。

好吧,除了讨论之外@FunctionalInterface的信息性注释是多么有用(我很高兴Java 8并不要求它用于lambdas)。

Comparable通常是类型的属性,因此不是function接口的良好候选者。 它被明确地描述为自然排序,并没有采用两个这个/那个参数。 所以这个属性使得任何方法都不可能在lambda上运行(similliar参数适用于几乎所有的接口)。

因此,集合设计者为该任务使用第二个接口: Comparator ,为此,实现它的lambda是一个非常自然的选择。

没有机制可以防止天真地使用不打算成为function接口的接口。 通过使用像@NotFunctional这样的附加注释,它可以由接口的设计者显式声明,它不应该用作lambda。 默认情况下,如果没有指定注释,则可以认为它与@Functional一样好,目前就是这种情况。