29

Why does the following code not compile.

Consumer con = (s) -> System.out::println;

It says

The target type of this expression must be a functional interface

even though Consumer is a Functional Interface. The below works just fine.

Consumer con2 = (s) -> {System.out.println(s);};

fluffyBatman
  • 6,524
  • 3
  • 24
  • 25
HariJustForFun
  • 521
  • 2
  • 8
  • 17

2 Answers2

21

Because that's a method reference, the usage is a bit different:

 Consumer<String> c = System.out::println;

The argument that the consumer takes (s) will be still passed to the println method.

here is Oracle's tutorial on this.

Eugene
  • 117,005
  • 15
  • 201
  • 306
11

Consumer con = (s) -> System.out::println;

Here, you're trying to invoke the System.out.println() with what we call method reference in Java 8. When you're to reference a method in lambda expression its must be of like this,

Consumer con = System.out::println;

You don't actually need the s to call println method. Method reference will take care of that. This :: operator means you'll call the println method with a parameter and you don't going to specify its name.

But when you do this,

Consumer con2 = (s) -> {System.out.println(s);};

you're telling the lambda expression to explicitly println the content of s which is perfectly fine technically so it doesn't arise any compile error.

fluffyBatman
  • 6,524
  • 3
  • 24
  • 25