Ambiguous varargs methods

There are 3 phases used in overload resolution (JLS 15.2.2):

  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

  2. The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

  3. The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

In your example, both methods are variable arity methods, so the third phase applies.

Now, since we have two methods to choose from, we look for the more specific method.

JLS 15.12.2.5. Choosing the Most Specific Method says :

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

One applicable method m1 is more specific than another applicable method m2, for an invocation with argument expressions e1, …, ek, if any of the following are true:

m2 is not generic, m1 and m2 are applicable by variable arity invocation, and where the first k variable arity parameter types of m1 are S1, …, Sk and the first k variable arity parameter types of m2 are T1, …, Tk, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ k). Additionally, if m2 has k+1 parameters, then the k+1’th variable arity parameter type of m1 is a subtype of the k+1’th variable arity parameter type of m2.

In your case you have two non-generic methods which are applicable by variable arity invocation (i.e. both have varargs). In order for one of the methods to be chosen when you call method(1), one of them has to be more specific than the other. In your case, each method only has one parameter, and for one of them to be more specific than the other, the type of that one parameter must be a subtype of the other method’s parameter.

Since int is not a sub-type of Integer and Integer is not a sub-type of int, neither of your methods is more specific than the other. Hence the The method method(int[]) is ambiguous for the type Test error.

An example that would work :

public static void method(Object... x) {
    System.out.println("varargs");
}

public static void method(Integer... x) {
    System.out.println("single");
}

Since Integer is a sub-type of Object, the second method would be chosen when you call method(1).

Leave a Comment