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

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

The following code surprisingly is compiling successfully:

Consumer p = \"\"::equals;

This too:

p = s -> \         


        
3条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-27 15:46

    First, it's worth looking at what a Consumer actually is. From the documentation:

    Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.

    So it's a function that accepts a String and returns nothing.

    Consumer p = ""::equals;
    

    Compiles successfully because equals can take a String (and, indeed, any Object). The result of equals is just ignored.*

    p = s -> "".equals(s);
    

    This is exactly the same, but with different syntax. The compiler knows not to add an implicit return because a Consumer should not return a value. It would add an implicit return if the lambda was a Function though.

    p = s -> true;
    

    This takes a String (s) but because true is an expression and not a statement, the result cannot be ignored in the same way. The compiler has to add an implicit return because an expression can't exist on its own. Thus, this does have a return: a boolean. Therefore it's not a Consumer.**

    p = s -> ("".equals(s));
    

    Again, this is an expression, not a statement. Ignoring lambdas for a moment, you will see the line System.out.println("Hello"); will similarly fail to compile if you wrap it in parentheses.


    *From the spec:

    If the body of a lambda is a statement expression (that is, an expression that would be allowed to stand alone as a statement), it is compatible with a void-producing function type; any result is simply discarded.

    **From the spec (thanks, Eugene):

    A lambda expression is congruent with a [void-producing] function type if ... the lambda body is either a statement expression (§14.8) or a void-compatible block.

提交回复
热议问题