bug with varargs and overloading?

The problem is that it is ambiguous.

doIt(1, 2);

could be a call to doIt(int ...), or doIt(double ...). In the latter case, the integer literals will be promoted to double values.

I’m pretty sure that the Java spec says that this is an ambiguous construct, and the compiler is just following the rules laid down by the spec. (I’d have to research this further to be sure.)

EDIT – the relevant part of the JLS is “15.12.2.5 Choosing the Most Specific Method“, but it is making my head hurt.


I think that the reasoning would be that void doIt(int[]) is not more specific (or vice versa) than void doIt(double[]) because int[] is not a subtype of double[] (and vice versa). Since the two overloads are equally specific, the call is ambiguous.

By contrast, void doItAgain(int) is more specific than void doItAgain(double) because int is a subtype of double according the the JLS. Hence, a call to doItAgain(42) is not ambiguous.

EDIT 2 – @finnw is right, it is a bug. Consider this part of 15.12.2.5 (edited to remove non-applicable cases):

One variable arity member method named m is more specific than another variable arity member method of the same name if:

One member method has n parameters and the other has k parameters, where n ≥ k. The types of the parameters of the first member method are T1, . . . , Tn-1 , Tn[], the types of the parameters of the other method are U1, . . . , Uk-1, Uk[]. Let Si = Ui, 1<=i<=k. Then:

  • for all j from 1 to k-1, Tj <: Sj, and,
  • for all j from k to n, Tj <: Sk

Apply this to the case where n = k = 1, and we see that doIt(int[]) is more specific than doIt(double[]).


In fact, there is a bug report for this and Sun acknowledges that it is indeed a bug, though they have prioritized it as “very low”. The bug is now marked as Fixed in Java 7 (b123).

Leave a Comment