Search code examples
javafunctional-interface

"The target type of this expression must be a functional interface" even though it is


Okay so I'm feeling pretty dumb here. I ran into this problem in my Eclipse today and for the world I can't figure out what the problem is.

It's very simple. The following compiles:

MockCreationListener l = (mock, settings) -> {};
Mockito.framework().addListener(l);

The following does not:

Mockito.framework().addListener((mock, settings) -> {});

I know already that this is some silly thing I overlooked but what is the difference between these two bits of code?


Solution

  • This is because addListener accepts a MockListener interface. which is a marker interface with no methods.

    As you may know, lambdas can only be converted to interfaces with exactly one abstract method. So Java can't convert your lambda to MockListener. Without any other information, it doesn't know what functional interface it should convert your lambda to, so it outputs an error.

    Of course, you know that it should be MockCreationListener, but the compiler can't figure it out just by looking at the context. It could be anything that implements MockListener and also accepts two parameters and returns void, as far as the compiler is concerned.