Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 886
ziggy Avatar asked Jan 02 '12 14:01

ziggy


1 Answers

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:

  • JLS 15.12.2 Compile-Time Step 2: Determine Method Signature
like image 125
axtavt Avatar answered Oct 22 '22 03:10

axtavt