This behaviour is due to the fact that int is more specific than double while there is no such comparison between int and boolean.
As specified in the JLS section 15.12.2.5 (emphasis mine):
One applicable method m1 is more specific than another applicable method m2, for an invocation with argument expressions e1, ..., ek, if any of the following are true:
- ...
- m2 is not generic, and m1 and m2 are applicable by variable arity invocation, and where the first k variable arity parameter types of m1 are S1, ..., Sk and the first k variable arity parameter types of m2 are T1, ..., Tk, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ k). Additionally, if m2 has k+1 parameters, then the k+1'th variable arity parameter type of m1 is a subtype of the k+1'th variable arity parameter type of m2.
What more specific actually means is later defined with subtyping:
A type S is more specific than a type T for any expression if S <: T.
This means that S is more specific than T is S is a subtype of T. For primitive types, this comes down to the following properties:
- double > float
- float > long
- long > int
- int > char
- int > short
- short > byte
Notice that boolean is not there.
As such,
public static void main(String[] args) {
movie();
}
static void movie(int... x) { }
static void movie(short... x) { }
static void movie(double... x) { }
static void movie(byte... x) { }
compiles and movie(byte... x) will be called because it is the most specific.
However,
public static void main(String[] args) {
movie();
}
static void movie(int... x) { }
static void movie(boolean... x) { }
does not compile because boolean cannot be compared to int.