27

I stumbled upon the following Java code which is using a method reference for System.out.println:

class SomeClass {
    public static void main(String[] args) {
           List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9);
           numbers.forEach(System.out::println);
        }
    }
}

What is the equivalent lambda expression for System.out::println?

Saikat
  • 14,222
  • 20
  • 104
  • 125
Steve
  • 889
  • 1
  • 12
  • 26

2 Answers2

61

The method reference System.out::println will evaluate System.out first, then create the equivalent of a lambda expression which captures the evaluated value. Usually, you would use
o -> System.out.println(o) to achieve the same as the method reference, but this lambda expression will evaluate System.out each time the method will be called.

So an exact equivalent would be:

PrintStream p = Objects.requireNonNull(System.out);
numbers.forEach(o -> p.println(o));

which will make a difference if someone invokes System.setOut(…); in-between.

Naman
  • 27,789
  • 26
  • 218
  • 353
Holger
  • 285,553
  • 42
  • 434
  • 765
  • I do understand that invocation target of a method reference is evaluated `when its declaration is first encountered`, that is logical to me. But is there a jls part that explicitly says this(I've really tried to find it... ). If invocation target is a method, one could capture the method and `this` for example, not the actual object that the method returns... as far as I understand. Or did I get that entirely wrong? – Eugene Jun 15 '17 at 13:32
  • never mind... `First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated` – Eugene Jun 15 '17 at 13:34
6

It's :

numbers.forEach(i -> {System.out.println(i);});

or even simpler :

numbers.forEach(i -> System.out.println(i));
Eran
  • 387,369
  • 54
  • 702
  • 768