deamon
deamon

Reputation: 92519

Ambiguous method call with Lambda in Java

I have defined a static assertThat method to extend AssertJ. This method accepts a lambda expression of the type:

@FunctionalInterface
public interface Action {
  void execute() throws Exception;
}

The signature looks like this:

public static ExceptionAssert assertThat(Action action)

I want to use this method with a static import. But it is ambiguous. The compiler doesn't know whether assertThat(Iterable) or my method should be used. I don't understand how a void method can conflict with a method that returns an Iterator<T>.

Any idea how to resolve this conflict (without writing the class name in front of assertThat)?

Upvotes: 10

Views: 6053

Answers (4)

Ross
Ross

Reputation: 26

I just encountered the same problem and as brafdlog suggested upgrading to a newer version of eclipse fixed it. Except in my case I was already on 4.4.2 (Spring Tool Suite 3.6.4) and upgraded to the latest Eclipse Neon 4.6.1 fixed it.

Upvotes: 0

brafdlog
brafdlog

Reputation: 2692

I had the same problem with eclipse version 4.4.1
Upgrading to 4.4.2 solved it.

Upvotes: 0

Holger
Holger

Reputation: 298469

I don't understand how a void method can conflict with a method that returns an Iterator<T>.

The only way you can have such a conflict is when your lambda expression never completes normally, e.g. ()->{ throw new RuntimeException(); } or ()->{ for(;;); }.

(or if your lambda expression consist of a single method invocation which indeed returns an Iterable)

For all other cases you are right, there shouldn’t be such a conflict and, indeed I could compile equivalent code without any problems with jdk1.8.0_20 for ordinary lambda expressions (you didn’t include the code which triggers the error in your question).

If you experienced the problem with a lambda expression which can complete normally and have used an older jdk, you ran into the bug discussed here. This answer refers to the language specification part specifying the difference between void-compatible and value-compatible lambda expressions.

If you used a different compiler or IDE, e.g. Eclipse, make sure you are using the most recent version and file a bug report, if this error still occurs.

Upvotes: 1

Dmitry Ginzburg
Dmitry Ginzburg

Reputation: 7461

You should specify the type of lambda explicitly:

assertThat((Action)() -> {
    ...
});

The other option is just using the other name, for example, assertNoException

Upvotes: 17

Related Questions