In substance, to determine which method is applicable, the compiler runs a few steps:
- first trying to find a method without using boxing/unboxing or varargs
- second trying to find a method, allowing boxing / unboxing, but without varargs
- third allowing boxing, unboxing and varargs
In your case, the third step is applicable to all methods.
The compiler then determines which methods are applicable and if one is more specific than another. The detailed rules are in the JLS 15.12.2.4. In short, it looks at the types and checks if one is more specific than another (i.e. one type is a subclass of the other for references or one type is narrower than another for primitives).
In your case:
- in example 1, both methods are applicable but
int
is more specific than long
so the vararg(int...)
is chosen
- in example 2,
Integer
has no specificity relationship with long
(one is a reference the other is a primitve), so both are maximally specific and there is an ambiguity which leads to a compile error.
EDIT
I thought you were saying that your first example compiles but not the second (which is the expected behaviour). You seem to be saying that neither compiles, in which case it is probably due to a bug in you version of javac
, which has been fixed with Java 7. See details in the release notes, section called "Changes in Most Specific Varargs Method Selection".