Search code examples
javaoopwrapperscjp

Does wrapper widening beat unboxing?


class Dec26 {
    public static void main(String[] args) {
        short a1 = 6;
    new Dec26().go(a1);
    new Dec26().go(new Integer(7));
 }
 void go(Short x) { System.out.print("S "); }
 void go(Long x) { System.out.print("L "); }
 void go(int x) { System.out.print("i "); }
 void go(Number n) { System.out.print("N "); }
 }

Output:

i N

In the above example, why does the compiler choose the widening option (i.e. Integer --> Number) instead of unboxing the Integer and choosing the int option?

Thanks


Solution

  • Your question is not about precedence of conversions in general, it's about details of overload resolution algorithm.

    For backward compatibility reasons, process of overload resolution consists of 3 phases:

    • Phase 1: Identify Matching Arity Methods Applicable by Subtyping
      • ignores varargs and boxing/unboxing
    • Phase 2: Identify Matching Arity Methods Applicable by Method Invocation Conversion
      • ignores varargs but respects boxing/unboxing
    • Phase 3: Identify Applicable Variable Arity Methods
      • supports all possible conversions

    If compiler fails to identify potentially applicable methods at one phase, it proceeds to the next one, overwise it analyzes potentially applicable methods to choose the most specific one and uses it for the invocation.

    As you can see, in your case both invocations are applicable by subtyping (short is a subtype of int, Integer is a subtype of Number), therefore they are resolved on phase 1, so that overload resolution process never reaches phase 2 and possible unboxing is ignored.

    See also: