如何比较Java8中的函数接口/方法引用

如何比较Java8中的函数接口/方法引用,java,lambda,java-8,Java,Lambda,Java 8,是否可以执行以下操作: boolean isItMyMethod( Consumer<Object> aConsumer ) { return aConsumer.equals( this::myMethod ); } 布尔isItMyMethod(消费者A消费者) { 返回aConsumer.equals(this::myMethod); } 这是不可编译的。如果我将this::myMethod分配给中间变量,则会发生这种情况,但结果总是false。方法引用或lambd

是否可以执行以下操作:

boolean isItMyMethod( Consumer<Object> aConsumer )
{
    return aConsumer.equals( this::myMethod );
}
布尔isItMyMethod(消费者A消费者)
{
返回aConsumer.equals(this::myMethod);
}

这是不可编译的。如果我将this::myMethod分配给中间变量,则会发生这种情况,但结果总是false。

方法引用或lambda的目标类型应该是函数接口。由于
equals()
方法接受一个
对象,该对象不是函数接口,因此无法编译。现在你会说,为什么?嗯,lambda表达式或方法引用在运行时实现为实现该函数接口的类的实例。FI只包含一个抽象方法,因此对于lambda
x->Sysout(x)
,左侧部分成为该方法的参数,右侧部分成为主体

现在可以有很多功能接口,提供这样的方法签名。这意味着可以编译相同的lambda表达式来实现不同的FIs。现在,当您将lambda传递给
对象
引用时,如下所示:

Object ob = x -> Sysout(x);
public boolean equals(Object ob) {
    return this == ob;
}
您希望JVM实例化哪个FI?这会导致某些歧义,因此是不允许的。但通过将lambda预分配给FI参考:

Consumer<Object> consumer = x -> Sysout(x);
至于为什么
equals()
方法返回
false
,您可以猜出来。由于lambda是在运行时构造的类的实例,它将在FI中提供抽象方法的实现,您希望在什么基础上比较两个
使用者
引用?由于没有覆盖的
equals()
方法,因此它将调用
Object
类中的实现,该类仅比较引用。实现如下所示:

Object ob = x -> Sysout(x);
public boolean equals(Object ob) {
    return this == ob;
}

当然
aConsumer==bConsumer
将返回
false
,如果两者都引用了两个不同的lambda/方法引用。

myMethod的类型是什么?用例是什么?为什么要这样做?顺便说一句,直接传递方法引用不起作用,因为lambda和方法引用的目标类型应该是函数接口,而
对象
不是函数接口。无论如何,您不能依赖lambda或方法引用上的
.equals
来返回一致的结果。或者,换句话说,在当前实现中,您可以说
consumerc1=this::myMethod,c2=this::myMethod
和两者,
c1==c2
c1.equals(c2)
,将计算为
false
。因此,您可以将代码修复为
aConsumer.equals((Consumer)this::myMethod)
,但它总是会产生
false
(使用当前的JRE实现)。另请参见
aConsumer==bConsumer
可能返回
false
,即使两者都引用相同的lambda表达式/方法引用…为什么不重写
equals()