Why does this not produce an ambiguity?

141 Views Asked by At

I just wrote some code with the following structure:

public void method(int x) {
    //...
}

public void method(int x, String... things) {
    //...
}

I was rather surprised that this compiled, and that if I invoked

method(3);

then it would pick the first one. Obviously this is in some sense the natural one to pick, but if the first method didn't exist, this would be a reasonable way of invoking the second (with an empty varargs array). So surely it should be considered ambiguous and produce a compile-time error?

Or is this treated as a special case?

It seems wrong to treat it as such, because it means that adding a new method could break existing code, and that is not a very happy state of affairs.

(Goodness only knows which one you'd end up invoking if the first one were added as a new method of a subclass containing the second one...)

2

There are 2 best solutions below

0
On BEST ANSWER

According to Chapter 15 of the Java Language specification, the search for an applicable method is done in three phases.

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.

So, the first method is considered applicable in the first phase already. The rest of the phases are skipped; the String... method would only be considered in the third phase:

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

0
On

The argument type of the first method is

int x

The argument types of the second method are

int x, String[] things

Therefore the two methods do not have the same signature and there is no ambiguity. @Glorfindel explains how Java decides which method to invoke, but if you wanted to invoke the second method without any things, you can pass in an empty array.

method(6, new String[0]);