Following code was successfully compiled
class Overloading{
public static void aMethod (double val1, long val2) {
System.out.println ("double, long");
}
public static void aMethod (int val1, long val2) {
System.out.println ("int, long");
}
public static void main(String[] args) {
aMethod(9, 10);
}
}
But when method signature was changed
From this
aMethod (double val1, long val2)
To this
aMethod (double val1, int val2)
compilation time error was occured
Overloading.java:12: error: reference to aMethod is ambiguous, both method aMeth
od(double,int) in Overloading and method aMethod(int,long) in Overloading match
aMethod(9, 10);
^
Firstly, the JVM doesn't resolve overloads - the compiler does. (Whereas the JVM decided which overridden method to execute, for example.)
As for why the method call becomes ambiguous - the compiler is looking for a single method where every conversion from the method argument type (int
for both arguments) to the method parameter type (int
, long
or double
) is at least as specific as the corresponding conversion in other candidate methods.
The conversion from int
to int
is more specific than the conversion from int
to double
, so your second overload "wins" in both cases.
For the second parameter, in your original code it's a conversion from int
to long
for both overloads, so that means the second overload "wins" overall.
In your modified code, the conversion from int
to int
is more specific than the conversion from int
to long
, so the first overload "wins" for this parameter. So each overload is better than the other for one parameter, and the invocation is ambiguous.
See JLS section 15.12.2 (and the sections it refers to and contains, particularly 15.12.2.5) for all the gory details.
See more on this question at Stackoverflow