Why is there an ambiguous error when using varargs overload with primitive type and wrapper class?

I do not understand why here in case 1, it does not give a compilation error, otherwise in case 2 (varargs) it gives a compilation error. Can someone explain what differences the compiler makes in these two cases? I looked through a lot of posts about this, but still could not understand.

Case No. 1

public class Test { public void display(int a) { System.out.println("1"); } public void display(Integer a) { System.out.println("2"); } public static void main(String[] args) { new Test().display(0); } } 

Output: 1

Case No. 2

 public class Test { public void display(int... a) { System.out.println("1"); } public void display(Integer... a) { System.out.println("2"); } public static void main(String[] args) { new Test().display(0); } } 

Compilation Error :

 The method display(int[]) is ambiguous for the type Test 
+7
java overloading primitive wrapper variadic-functions
source share
2 answers

In the first example, the display(int) method is called in the strict context of the call, while display(Integer) is called in the free context of the call (since automatic boxing is required). Thus, the compiler chooses the display(int) method according to JLS. The JLS 5.3 call contexts are described here . Call Contexts

In the second example, both methods are called in the free context of the call, so the compiler needs to find the most specific JLS method 15.12.2.5 Choosing the most specific method . Since int is not a subtype of Integer, there is no particular method, and the compiler generates a compilation error.

You can find my explanation of a similar compilation error here. The method overloads ambiguity with the help of three-dimensional thermal conditional and unboxed Java 8 primitives.

Parts that apply to this case:

Identification of applicable methods is divided into 3 phases.

The first phase (§15.12.2.2) performs overload resolution without allowing boxing or unpacking the conversion, or using a variable to call the arity method . If during this phase then processing continues to the second phase.

The second phase (§15.12.2.3) performs overload resolution, allowing boxing and unpacking , but still excludes use . If a suitable method is not found at this stage, processing continues until the third phase.

The third stage (§15.12.2.4) allows you to combine overloading with the methods of the arity variable , boxing and unpacking.

In the first example, only the display(int) method is mapped in the first phase, so it is selected. For the second example, both methods are compared in the 3rd phase, therefore the JLS algorithm “Choosing the most specific method” comes into play JL 15.12.2.5 Choosing the most specific method :

m2 is not common, and m1 and m2 are applicable to the variable arity invocation and where the first k variable parameters of arity types m1 are S1, ..., Sk and the first k variable parameter parameters arty m2 T1, ..., Tk, type Si more specific than Ti for the argument ei for all i (1 ≤ i ≤ k). In addition, if m2 has k + 1 parameters, then the k + 1-st type parameter of arity m1 is a subtype of the k + 1'-variable parameter of arity m2.

As mentioned earlier, there is no particular method since int & lt :: Integer does not satisfy.

+5
source share

After java version 1.5, a wonderful feature called autoboxing that allows the compiler to convert a primitive type The type of wrapper . Thus, at compile time, both methods will work the same.

  public void display(int... a) { System.out.println("1"); } public void display(Integer... a) { System.out.println("2"); } 

both functions will be processed as the same method, since autoboxing executes the compilation command. Therefore, be careful with Auto-Boxing when overloaded in Java.

You will find more details here ..

Method overload guidelines

-one
source share

All Articles