Skip to content
Advertisement

Java compiler: How can two methods with the same name and different signatures match a method call?

I have this class called Container:

JavaScript

and the class called Token:

JavaScript

and finally a test class for the Token class

JavaScript

The test compiles and runs just fine in eclipse.

When building on the commad line

JavaScript

a compile error is raised:

JavaScript

The compilation also fails when I change line 21 to one of

JavaScript

When I change the line to one of

JavaScript

compilation is successful.

I cannot undestand why this compiliation error is raised.

I came across the follwong links boxing and unboxing, multiple generic types and intersection types and this eclipse compiler bug but I still cannot relate to the mentioned causes.

My question is, what makes the compiler think that both signatures of the verify method are matching when the mapper String::valueOf is passed to the get method?

For compilation the following jdk is used (with maven and gradle):

JavaScript

Advertisement

Answer

According to the JLS §15.12.2.2:

An argument expression is considered pertinent to applicability for a potentially applicable method m unless it has one of the following forms:

  • An implicitly typed lambda expression1.
  • An inexact method reference expression2.
  • […]

Therefore:

JavaScript

an implicitly typed lambda expression e -> String.valueOf(e) is skipped from the applicability check during overload resolution – both verify(...) methods become applicable – hence the ambiguity.

In comparison, here are some examples that will work, because the types are specified explicitly:

JavaScript

1 – An implicitly typed lambda expression is a lambda expression, where the types of all its formal parameters are inferred.
2 – An inexact method reference – one with multiple overloads.

Advertisement