In the first case, there is no error because the parameter types of these two methods are different, and there is no overloading ambiguity. The compiler can unambiguously determine which method to call based on the type of argument passed during the invocation.
What about the 2nd and 3rd tests, here everything is much more interesting. Varargs automatically wrap primitive data types into their corresponding wrapper classes if the method takes the varargs that correspond to primitive types. (byte...
=> Byte...
when calling a method).
In the 2nd case, if you call doCalc(12, 1)
for example, 12
and 1
are treated as int
literal, but it can be automatically transfered into a long
(int -> long). So the method doCalc(long... a)
has an advantage because it can directly accept an argument of type long
(cannot convert from int
to byte
for int -> byte -> Byte
, but can from int
to long
), which is a primitive long
.
I got the next output here: byte 2...
But you can call the method as follows:
byte b = 1;
doCalc(b, b);
In this case, there will be a compile-time error, because it can convert byte -> int -> long
and also it can convert byte -> Byte
as well.
Also, you can experiment with the methods like that:
static void doCalc(Long... a) {
System.out.print("byte 2...");
}
Here even if you call doCalc(1, 1)
, there will be an compile-time error, because it can't wrap int
into Long
.
What about 3rd case, you have two non-generic methods (Byte...
vs Byte...
). In order for one of the methods to be chosen, one of them has to be more specific than the other. In your case, each method only has one parameter, and for one of them to be more specific than the other, the type of that one parameter must be a subtype of the other method's parameter.
Since byte
is not a subtype of Byte
there is no most specific method and the compiler throws a compile-time error.
Check this out. JLS 15.12.2.5 Choosing the Most Specific Method: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
Also, check these answers:
- Method overload ambiguity with Java 8 ternary conditional and unboxed primitives
- Why is this method overloading ambiguous?