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
.