1

declaring an IntConsumer like this:

int z = 0;
IntConsumer iConsumer = (a) -> z;

gives a compilation error: "Void methods cannot return a value". Ok

But like this :

int z = 0;
IntConsumer iConsumer = (a) -> Function.identity().apply(z);        

When Function.identity().apply(z) returns an Object, no compilation error here.

Shouldn't also give a compilation error?

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
fidudidu
  • 399
  • 3
  • 10
  • https://stackoverflow.com/questions/41482574/lambda-special-void-compatibility-rule-statement-expression – Koray Tugay Aug 04 '19 at 12:05
  • This is a Function and not a "special" statement as described by that question you refer. A Function, where: "R apply(T t)" method will always return R (which is not void), so the compiler knows at compile-time check that this method will never return void so why does it accept as valid and "forget" the value that is returned? – fidudidu Aug 04 '19 at 12:21
  • @fidudidu doesn't my post answer your question? `Function.identity().apply(z)` is an expression statement (specifically, a method invocation statement). From JLS: *"An expression statement is executed by evaluating the expression; if the expression has a value, the value is discarded."* – Andrew Tobilko Aug 04 '19 at 15:18

1 Answers1

1

z is always an expression.

Function.identity().apply(z) is an expression statement. It can be used as an expression since it returns a value. But it's interpreted as a statement as long as the value is being ignored.

An expression statement is executed by evaluating the expression; if the expression has a value, the value is discarded.

https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.8

IntConsumer#accept(int value) expects void to be returned. In case of a single-line lambda body, it must be a statement.

Compare

// not allowed - expressions
IntConsumer a = (i) -> 2 + 2;
IntConsumer b = (i) -> true ? 1 : 0;
IntConsumer c = (i) -> (Function.identity().apply(i));
IntConsumer d = (i) -> (System.out.println(i));
IntConsumer e = (i) -> (new Object());

// allowed - expression statements
IntConsumer f = (i) -> Function.identity().apply(i);
IntConsumer g = (i) -> System.out.println(i);
IntConsumer h = (i) -> new Object();
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142