Why does this Java 8 lambda fail to compile? Why does this Java 8 lambda fail to compile? java java

Why does this Java 8 lambda fail to compile?


Your lambda needs to be congruent with BiConsumer<String, String>. If you refer to JLS #15.27.3 (Type of a Lambda):

A lambda expression is congruent with a function type if all of the following are true:

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

So the lambda must either be a statement expression or a void compatible block:


Basicly, new String("hi") is an executable piece of code that actually does something (it creates a new String and then returns it). The returned value can be ignored and new String("hi") can still be used in void-return lambda to create a new String.

However, "hi" is just a constant that doesn't do anything on it's own. The only reasonable thing to do with it in lambda body is to return it. But the lambda method would have to have return type String or Object, but it returns void, hence the String cannot be casted to void error.


The first case is ok because you are invoking a "special" method (a constructor) and you are no actually taking the created object. Just to make it more clear, I'll put the optional braces in your lambdas:

takeBiConsumer((String s1, String s2) -> {new String("hi");}); // OKtakeBiConsumer((String s1, String s2) -> {"hi"}); // Error

And more clear, I'll translate that to the older notation:

takeBiConsumer(new BiConsumer<String, String>(String s1, String s2) {    public void accept(String s, String s2) {        new String("hi"); // OK    }});takeBiConsumer(new BiConsumer<String, String>(String s1, String s2) {    public void accept(String s, String s2) {        "hi"; // Here, the compiler will attempt to add a "return"              // keyword before the "hi", but then it will fail              // with "compiler error ... bla bla ...              //  java.lang.String cannot be converted to void"    }});

In the first case you are executing a constructor, but you are NOT returning the created object, in the second case you are attempting to return a String value, but your method in your interface BiConsumer returns void, hence the compiler error.