0

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);
                ^
Paresh Radadiya
  • 185
  • 4
  • 10
  • 2
    The overload resolution process is complex and arcane (see http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12), I don't propose to dig through it to figure out your particular example! In practice, it's rare that this sort of situation will come up (if it does, I'd recommend redesigning your methods...) – Oliver Charlesworth Jun 28 '14 at 11:37
  • In general it's a (very) bad idea to have overloaded methods where the only distinction is between different numeric types. Sometimes you've got to actually have method names which define which method to call. – Hot Licks Jun 28 '14 at 12:23
  • possible duplicate of [When using overloading with type promotion, why method calling is ambiguous?](http://stackoverflow.com/questions/22991150/when-using-overloading-with-type-promotion-why-method-calling-is-ambiguous) – Jeroen Vannevel Jun 28 '14 at 19:09

1 Answers1

4

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194