Methods with varargs (...
) have the lowest priority when the compiler determines which overloaded method to choose. Therefore TestOverload(int i)
is chosen over TestOverload(char... c)
when you call TestOverload
with a single char
parameter 'a'
, since a char
can be automatically promoted to an int
.
JLS 15.12.2 :
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.
This guarantees that any calls that were valid in the Java programming
language before Java SE 5.0 are not considered ambiguous as the result
of the introduction of variable arity methods, implicit boxing and/or
unboxing. However, the declaration of a variable arity method (§8.4.1)
can change the method chosen for a given method method invocation
expression, because a variable arity method is treated as a fixed
arity method in the first phase. For example, declaring m(Object...)
in a class which already declares m(Object) causes m(Object) to no
longer be chosen for some invocation expressions (such as m(null)), as
m(Object[]) is more specific.
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. This ensures that a method is never chosen through variable arity
method invocation if it is applicable through fixed arity method
invocation.
The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.
EDIT:
It you wish to force the compiler to call the TestOverload(char... c)
constructor, you can pass to the constructor call a char[]
:
new TestOverload (new char[] {'a'});
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…