Lambda Expression that has return type as void can compile with wrapper but not compile with primitive

Viewed 1352
   interface A {
        void s();
   }

  public static void main(String[] args) {
        A a = () -> 5; // DOES NOT compile
        A b = () -> new Integer(5); // does compile
        A c = () -> Stream.of(1, 2, 3); // does compile
    }

What is the reason that the first line does not compile and the second and third one does ?

2 Answers

Wrapper vs primitive is not the cause. The following will not compile either:

Integer i = 5;
A b = () -> i;

This is covered in JLS 15.27.3:

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

5 is neither a statement not a void-compatible block. So A a = () -> 5; will not compile.

The reason for this restriction is that void-returning lambda only makes sense if it operates by a side-effect. Simply returning a value like () -> 5 has no side effects and therefore such a lambda expression is definitely a bug.

when jvm compiles A a = () -> 5; it convert lambda expresssion as following

void s(){
  return 5; //
}

when jvm compiles A b = () -> new Integer(5); it convert lambda expresssion as following

 void s(){
       new Integer(5);
    }

Hence, until you won't perform initialization, expression would considered as return values.

Related