Just when I thought I understood JLS15.12 as it applied to varargs, here's this example:
package com.example.test.reflect;
public class MethodResolutionTest2 {
public int compute(Object obj1, Object obj2) {
return 42;
}
public int compute(String s, Object... objects)
{
return 43;
}
public static void main(String[] args) {
MethodResolutionTest2 mrt2 = new MethodResolutionTest2();
System.out.println(mrt2.compute("hi", mrt2));
System.out.println(mrt2.compute("hi", new Object[]{mrt2}));
System.out.println(mrt2.compute("hi", new Object[]{mrt2, mrt2, mrt2}));
}
}
which prints out
42
43
43
I understand the first line: JLS15.12 says method resolution happens in phases, and phases 1 and 2 ignore varargs methods to find out if there's a compatible method, with phase 3 (include varargs) happening only if phases 1 and 2 fail. (See the JLS and this SO question.) So compute(String s, Object... objects)
always gets ignored if compute(Object obj1, Object obj2)
applies.
But I don't understand why 43 is printed for the other two lines. An Object[]
is also an instance of an Object
, so why does it match the varargs method?
edit:
...and this
Object arg2 = new Object[]{mrt2};
System.out.println(mrt2.compute("hi", arg2));
prints 42
.
In section 8.4.1:
If the last formal parameter is a variable arity parameter of type
T
, it is considered to define a formal parameter of typeT[]
.
Since you're explicitly providing an array, this allows the second two calls to match the variable arity method in the first phase, without consideration of variable arity.
Vararg methods can be called with multiple parameters (a, b, c) or as an array ({a, b, c}). Because you are passing an array that matches the type of the varargs it takes precedence.
Reference: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With