Diwakar Bhatt
Diwakar Bhatt

Reputation: 515

The target type of expression must be a functional interface – why is this needed?

I have gone through lots of questions which have the same headline but I didn't get the answer I am looking for.

In Greeter class below there is a simple sysout. As I understand it, what lambda cares about is the signature (i.e. return type and no. of parameters). But if i remove

int add(int a);

it perfectly works, because compiler will check that there is any method available in Greeting interface which has no arguments and whose return type is void.

But when I keep that method there, I get the compilation error mentioned in subject line, as per my understanding compiler will go to Greeting interface and it will see there are two methods. However there should be no ambiguity because my lambda expression looks for the method whose return type is void and only one argument. Based on this analogy there is only one method so ideally it should not give error.

I know that my analogy is wrong here, I do know that it must be a functional interface, but I also think that the process which I have mentioned above is exactly how the compiler is going to work.

Can anyone please let me know where I am wrong and how the compiler is actually working in my example?

Greeting Interface

package lambadas;

public interface Greeting {
    void perform();
    int add(int a);
}

Greeter class

package lambadas;

public class Greeter {

    public static void main(String[] args) {
        Greeting l = () -> System.out.println("hello");
        l.perform();
    }
}

HelloWorldGreeting

package lambadas;

public class HelloWorldGreeting implements Greeting {

    @Override
    public void perform() {
        System.out.println("hello world.!");
    }
    @Override
    public int add(int a) {
      return 0;
    }

}

Upvotes: 3

Views: 9718

Answers (2)

Didier L
Didier L

Reputation: 20579

Just start by asking yourself this question: if it was possible to implement Greeting that way, what would happen when calling l.add(0)? NoSuchMethodError? Undefined behaviour? You probably don't want that – and the language designers didn't want it either.

By enforcing functional interfaces as target types for lambda expressions, the compiler guarantees that you don't have partial implementations of those interfaces. This is exactly the same reason as for the compiler error you would get if HelloWorldGreeting did not implement add(int) either: you provide 1 implementation, but there are 2 methods to implement.

So this is not really about matching your lambda with a specific method, but instead it is about creating valid instances of the interface it implements.

Upvotes: 3

Eugene
Eugene

Reputation: 120848

Annotate your interface with @FunctionalInterface - and see it breaking. Only a single abstract method is allowed.

Upvotes: 5

Related Questions