The target type for a method reference, or a lambda, should be a functional interface. Since equals()
method takes an Object
, which is not a functional interface, it fails to compile. Now you would say, why? Well, a lambda expression or a method reference is at runtime implemented as an instance of a class implementing that functional interface. A FI contains just a single abstract method, thus for a lambda x -> Sysout(x)
, the left part becomes the parameter of that method, and right part becomes body.
Now there can be many functional interface, providing such method signature. That means same lambda expression can be compiled to implementation of different FIs. Now when you pass a lambda to an Object
reference like this:
Object ob = x -> Sysout(x);
which FI do you expect JVM to instantiate? This results in certain ambiguity, and hence is not allowed. But by pre-assigning a lambda to a FI reference:
Consumer<Object> consumer = x -> Sysout(x);
you've assigned a concrete meaning to the lambda, which then later on can be assigned to any of its super type reference.
Object ob = consumer;
Now as for why equals()
method returns false
, you can guess it. Since lambda is an instance of a class constructed at runtime, which would provide implementation of the abstract method in FI, on what basis would you want two Consumer
references to compare? Since there is no equals()
method overridden, it will invoke the implementation in Object
class, which just compares the reference. Implementation looks like this:
public boolean equals(Object ob) {
return this == ob;
}
Certainly aConsumer == bConsumer
will return false
, if both are referring to 2 different lambdas / method references.