Why does this Java 8 lambda fail to compile?

后端 未结 4 1730
花落未央
花落未央 2020-12-08 06:16

The following Java code fails to compile:

@FunctionalInterface
private interface BiConsumer {
    void accept(A a, B b);
}

private static void t         


        
4条回答
  •  伪装坚强ぢ
    2020-12-08 06:57

    The JLS specify that

    If the function type's result is void, the lambda body is either a statement expression (§14.8) or a void-compatible block.

    Now let's see that in detail,

    Since your takeBiConsumer method is of void type, the lambda receiving new String("hi") will interpret it as a block like

    {
        new String("hi");
    }
    

    which is valid in a void, hence the first case compile.

    However, in the case where the lambda is -> "hi", a block such as

    {
        "hi";
    }
    

    is not valid syntax in java. Therefore the only thing to do with "hi" is to try and return it.

    {
        return "hi";
    }
    

    which is not valid in a void and explain the error message

    incompatible types: bad return type in lambda expression
        java.lang.String cannot be converted to void
    

    For a better understanding, note that if you change the type of takeBiConsumer to a String, -> "hi" will be valid as it will simply try to directly return the string.


    Note that at first I tought the error was caused by the lambda being in a wrong invocation context, so I'll share this possibility with the community :

    JLS 15.27

    It is a compile-time error if a lambda expression occurs in a program in someplace other than an assignment context (§5.2), an invocation context (§5.3), or a casting context (§5.5).

    However in our case, we are in an invocation context which is correct.

提交回复
热议问题