Why do Consumers accept lambdas with statement bodies but not expression bodies?

前端 未结 3 1136
不知归路
不知归路 2020-11-27 15:13

The following code surprisingly is compiling successfully:

Consumer p = \"\"::equals;

This too:

p = s -> \         


        
3条回答
  •  误落风尘
    2020-11-27 15:40

    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.

提交回复
热议问题