Variable arity comes last in determining the most specific method. The rules to determine which vararg method applies when there are several are defined in JLS 15.12.2.4 - here is an extract:
One variable arity member method named m is more specific than another
variable arity member method of the same name if either:
- [...]
- One member method has k parameters and the other has n parameters, where n ≥ k, and:
The types of the parameters of the first method are U1, ..., Uk-1,
Uk[]. The types of the parameters of the other method are T1, ...,
Tn-1, Tn[]. For all j from 1 to n, Uj <: Tj In your case, k = n, and
U1[] = int[] and T1[] = long[] so the determination can be made if int
<: long or the opposite.
In other words, the type taken into account is not int[] vs. long[]
but int vs long. And it happens that int <: long so the int... method
should be chosen and it should compile.
Conclusion:
The code should (and does) compile fine with Java 7 but would not compile with Java 5 or 6. The code below prints int with Java 7:
public class Test1 {
public static void main(String[] args) {
new Test1().m(1, 2);
}
int m(int... i) {
System.out.println("int");
return 0;
}
long m(long... i) {
System.out.println("long");
return 0;
}
}