1

I am trying to learn assertThrows in junit5, it takes Executable as 2nd arg which has a void execute() method. But while going through the example on the same in the below example we are passing it a LAMBDA which returns a double with method double divide(int a , int b). Now how is it possible to pass the below lambda if it does not have the same signature as the execute method of the Excecutable. It should give compile error right?

assertThrows(ArithmeticException.class,() -> m.divide(1, 0),"Failed");
ghostrider
  • 2,046
  • 3
  • 23
  • 46

1 Answers1

6
() -> m.divide(1, 0)

is treated effectively like

new Executable() {
  @Override public void execute() {
    m.divide(1, 0);
  }
}

The lambda can be treated like an instance of any interface/class with a single abstract method.

Lambdas are always polyexpressions, meaning that their exact type is determined by the context in which they are used.

There is no compatibility issue.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • But divide will return a double whereas execute is void. Will the result be absorbed? I am confused :( – ghostrider Feb 09 '20 at 14:29
  • 2
    @ghostrider: That a method returns a value does not imply that you have to do something with it. In this case the compiler correctly resolves the expression and discards the returned value. – second Feb 09 '20 at 14:45
  • Then why do we get compilation error when we return something from a void method in a simple void method? – ghostrider Feb 09 '20 at 14:51
  • 2
    @ghostrider: Because thats invalid syntax (you manually defined), whereas in this case the compiler automatically knows the correct syntax to use. – second Feb 09 '20 at 14:53
  • 1
    @ghostrider the return value will simply be ignored. It's a *void-compatible* lambda. – Andy Turner Feb 09 '20 at 17:14
  • 1
    See also [this answer](https://stackoverflow.com/a/41483237/2711488) and [that answer](https://stackoverflow.com/a/37318579/2711488) – Holger Feb 10 '20 at 09:18