简体   繁体   中英

Weird behavior when overloading using variable arguments with primitive types in java

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:

  1. The method call z4() fits the signature of both variants.
  2. The method call z4(4) also fits the signature of both variants because the variable can be auto-boxed.
  3. The method call 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM