26

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
  • 11,375
  • 15
  • 92
  • 108
Steve
  • 777
  • 1
  • 11
  • 23

2 Answers2

57

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
  • 21,685
  • 24
  • 196
  • 332
Holger
  • 267,107
  • 35
  • 402
  • 715
  • 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
  • 374,785
  • 51
  • 663
  • 734