The Java compiler must choose between two matching methods. He will always choose a method that does not use the arity (varargs) variable over the one that uses it. This would rather contribute to all 3 int arguments to match the first printValue than using varargs.
Section 15.12.2 of the JLS states:
The rest of the process is divided into three phases to ensure compatibility with Java programming language versions prior to Java SE 5.0. Phase:
- The first phase (§15.12.2.2) performs overload resolution without allowing box conversion or unboxing, or using the method call of the arity variable . If no applicable method is found at this stage, processing continues until the second phase.
This ensures that any calls that were valid in the Java programming language prior to Java SE 5.0 are not considered ambiguous as a result of the implementation of arity variable methods, implicit boxing and / or decompression. However, declaring a method to an arity variable (§8.4.1) may change the method chosen to express the method call of this method, since the arity variable method is considered as a fixed arity method in the first phase. For example, declaring m (Object ...) in a class that already declares m (Object) causes m (Object) to no longer be selected for some invocation expressions (such as m (null)), like m (Object [])) is more specific.
- The second phase (§15.12.2.3) performs overload resolution when allowing boxing and unpacking, but still eliminates the use of the method invocation of the arity variable. If at this stage no applicable method is found, processing continues until the third phase.
This ensures that the method is never selected by calling the method of the arity variable, if applicable by calling the fixed arity method.
- The third stage (§15.12.2.4) allows you to combine overloading with the methods of the variable arity , boxing and unpacking.
(my bold accent)
The matching method (first overload) is found in the first phase, so the compiler does not even consider the third phase - the methods of the arity variable allow - therefore, an int is printed.
One way to select the second overload (which counterintuitively prints long ) is to create an array explicitly so that the first overload cannot match.
printValue(new byte[]{b,b,b});
source share