Clearly I've not enough knowledge of how overloading, autoboxing and variable arguments work.
So here's the program causing trouble whenever there's an involvement of primitive types.
public static void z(int a, Object...objects){
}
public static void z(Object...objects){
}
public static void main(String[] args) {
z(); // no error
z(4); // Compile time Error : Ambiguous
z2(); // No error
z2(true, "sadas"); // Error
// No problem with reference types
z3(); // No error. String one called
z3(5); // No error. Object one called
z4(); // Error
z4(4); // Error
z4("asdas"); // Working properly
}
public static void z2(boolean b, Object...objects){
}
public static void z2(Object...objects){
}
public static void z3(String...objects){
System.out.println("String one called");
}
public static void z3(Object...objects){
System.out.println("Object one called");
}
public static void z4(int...objects){
System.out.println("int z4 called");
}
public static void z4(Object...objects){
System.out.println("Object z4 called");
}
Can anybody explain why any of this is happening? I can happily use Integer, Boolean instead of int, boolean but would very much like to know internal working behind it.
A method call will not compile if the compiler cannot determine which of the overloaded method variants it should use.
Let's use z4
as an example:
z4()
fits the signature of both variants. z4(4)
also fits the signature of both variants because the variable can be auto-boxed. z4("asdas")
is not ambiguous, as String
cannot be cast to int
. Update : the rules for resolving overloaded method calls are as follows:
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
...
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
...
The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.
If more than one variant is selected in the same phase, then the most specific one is chosen,* but in short z3(String...)
is more specific than z3(Object...)
, while z4(int...)
and z4(Object...)
are equally specific.
*The rules for determining this most specific variant are somewhat complicated (see here )
Thats a fab question
Now consider
public static void z2(boolean b, Object... objects) {
}
public static void z2(Object... objects) {
}
Both methods have a vararg argument, which means they will both be considered on the third and final phase of overloading resolution.
Remember Object class is the mother of all objects in java
Well this explains one thing
The compiler can treat both as object which will result in object array again.
Now finally
void z2(boolean b, Object... objects)
public static void z2(Object... objects)
is treated as same function.
To check you can comment
z2(true);
z2(true, "sadas");
removing either of
public static void z2(boolean b, Object... objects) {
}
Or
public static void z2(Object... objects) {
}
This will work. But
You have taken object inside parameter
If you are specific for example
public static void z2(boolean b, String... objects) {
}
public static void z2(String... objects) {
}
z2(); // No error
z2(true, "sadas"); // No error
This way it can be resolved
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.