The following code surprisingly is compiling successfully:
Consumer p = \"\"::equals;
This too:
p = s -> \
s -> "".equals(s)
and
s -> true
don't rely on same function descriptors.
s -> "".equals(s) may refer either String->void or String->boolean function descriptor.
s -> true refers to only String->boolean function descriptor.
Why ?
s -> "".equals(s), the body of the lambda : "".equals(s) is a statement that produces a value.void or boolean.So writing :
Function function = s -> "".equals(s);
Consumer consumer = s -> "".equals(s);
is valid.
When you assign the lambda body to a Consumer declared variable, the descriptor String->void is used.
Of course, this code doesn't make much sense (you check the equality and you don't use the result) but the compiler doesn't care.
It is the same thing when you write a statement : myObject.getMyProperty() where getMyProperty() returns a boolean value but that you don't store the result of it.
s -> true, the body of the lambda : true is a single expression .boolean.String->boolean may be used.Now, come back to your code that doesn't compile.
What are you trying to do ?
Consumer p = s -> true;
You cannot. You want to assign to a variable that uses the function descriptor Consumer a lambda body with the String->void function descriptor.
It doesn't match !