Alright, I have taken a closer look at the JLS and I believe this should clear up any remaining doubts you might have.
This is the original problem:
public class Main {
private static void flipFlop(int i, Integer iRef) {
System.out.println("Method 1");
}
private static void flipFlop(int i, int j) {
System.out.println("Method 2");
}
public static void main(String[] args) {
flipFlop(new Integer(4), 2004);
}
}
As has been pointed out in the other answer: this fails because the compiler can't decide what overload to use.
However you might think this doesn't make any sense. The compiler can decide just fine in this situation what method he should use:
public class Main {
private static void flipFlop(Integer y) {
System.out.println("ciao");
}
private static void flipFlop(int j) {
System.out.println("hello");
}
public static void main(String[] args) {
flipFlop(new Integer(6));
flipFlop(6);
}
}
Rationality tells us that when you have values X
+ Y
and two methods that take respectively Y
+ X
and Y
+ Y
and you know that X
and Y
are interchangeable, then this would mean that the latter method is more specific.
The difference between these two are described in the JLS. I have provided the entire workflow below, but what matters is this:
First the compiler will look at methods with an equal signature while forbidding boxing/unboxing. In our second example this doesn't cause any problems, but in our first example this doesn't return a satisfiable method since neither of them take an Integer
as the first parameter..
When that failed, the compiler moves on to the second step where it allows boxing/unboxing. This should fix the issue we had with the first parameter, but now causes ambiguity with the second parameter since it is now uncertain whether you're referring to the overload using an int
or the one using an Integer
.
This ultimately results in an ambiguous method call.
15.12.2. Compile-Time Step 2: Determine Method Signature
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
If several applicable methods have been identified during one of the three phases of applicability testing, then the most specific one is chosen, as specified in section §15.12.2.5.
15.12.2.5. Choosing the Most Specific Method
A method is said to be maximally specific for a method invocation if it is accessible and applicable and there is no other method that is applicable and accessible that is strictly more specific.
It is possible that no method is the most specific, because there are two or more methods that are maximally specific. In this case:
If all the maximally specific methods have override-equivalent (§8.4.2) signatures, then: (... some rules to decide who's chosen ...)
Otherwise, we say that the method invocation is ambiguous, and a compile-time error occurs.