Theoretical query about overloading and type promotion in java

If there are two methods, for example add(int,long) and add(long,int) , such a call to add(10,10) will be considered an ambiguity.

But what if we have such an example, why is it still considered ambiguity?

 static void add(short num1, short num2) { System.out.println("add(short, short)"); } static void add(byte num1, long num2) { System.out.println("add(byte, long)"); } public static void main(String[] args) { byte num1 = 10; byte num2 = 10; add(num1, num2); } 

I want to know how the compiler decided this was ambiguity? while (in my opinion) this should not, because add(short, short) requires two steps of type promotion, and add(byte, long) requires three steps of type promotion .. or do I have a wrong idea ??

+7
java overloading type-promotion
source share
2 answers

See 8.4.9. Overloading - from the Java Language specification and "overloading the resolution procedure" - and, in particular, 15.12.2.5. The choice of the most specific method .

If more than one member method is available and applicable to a method call, you must select it to provide a handle to send the runtime. The Java programming language uses a rule in which the most specific method is selected.

..

One applicable method m1 is more specific than another applicable method m2, for calling arguments e1, ..., ek with expressions, if one of the following statements is true:

  • [..]

  • m2 is not general, and m1 and m2 are applicable by a strict or free call, and where m1 has formal parameter types S1, ..., Sn and m2 has formal parameter types T1, ..., Tn, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ n, n = k).

  • [..]

..

It is possible that none of the methods is the most specific, because there are two or more methods that are as specific as possible. [there are more wrt concrete / abstract rules ..]

Otherwise, the method call is ambiguous and a compile-time error occurs.

The Java compiler simply follows these rules; another language will follow different rules, and a person can come up with their own rules, other than Java, when choosing which overload to choose.


To select a method as more specific, it must be more specific for all parameters. Thus, the sample case leads to an ambiguous call when add(byte,byte) called, because:

  • add(short num1 /* less specific */, short num2 /* MORE specific */)
  • add(byte num1 /* MORE specific */, long num2 /* less specific */) .

However, if add(byte num1, long num2) was changed to add(byte num1, short num2) , it will compile because:

  • add(short num1 /* less specific */, short num2 /* as specific */)
  • add(byte num1 /* MORE specific */, short num2 /* as specific */) .

The connection between primitives is in 4.10.1. Subtyping among primitive types : long> int> short> byte:

+3
source share

If the actual argument types coincide with the method parameter lists, forced type coercion is required in both cases, therefore, none of them is "ideal" and therefore ambiguous. If you add

 static void add(byte num1, byte num2) { System.out.println("add(byte, byte)"); } 

this is a perfect match, and there is no ambiguity.

+1
source share

All Articles