The following code surprisingly is compiling successfully:
Consumer p = \"\"::equals;
This too:
p = s -> \
I think the other answers complicate the explanation by focusing on lambdas whereas their behavior in this case is similar to the behavior of manually implemented methods. This compiles:
new Consumer() {
@Override
public void accept(final String s) {
"".equals(s);
}
}
whereas this does not:
new Consumer() {
@Override
public void accept(final String s) {
true;
}
}
because "".equals(s) is a statement but true is not. A lambda expression for a functional interface returning void requires a statement so it follows the same rules as a method's body.
Note that in general lambda bodies don't follow exactly the same rules as method bodies - in particular, if a lambda whose body is an expression implements a method returning a value, it has an implicit return. So for example, x -> true would be a valid implementation of Function, whereas true; is not a valid method body. But in this particular case functional interfaces and method bodies coincide.