Why does this not produce an ambiguity? [duplicate]
Asked Answered
C

2

7

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...)

Collinsia answered 12/8, 2015 at 14:15 Comment(4)
You called a method with 1 parameter,why would it call the one with 2 needed?Anacreontic
@Anacreontic because there isn't one with two needed. The second has a varargs parameter, which means that the String... part can take any number of arguments, including zero.Collinsia
@Collinsia Ah I didn't know that was the Java equivalent, I thought you wrote ... because you were too lazy to find [] on the keyboardAnacreontic
vararg methods was introduced rather late in java5. they don't want existing code affected by it, therefore vararg methods are put in a low priority during method resolution.Israelitish
R
10

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.

Ravelment answered 12/8, 2015 at 14:21 Comment(0)
B
0

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]);
Bronnie answered 12/8, 2015 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.