Open In App

Method Overloading and Ambiguity in Varargs in Java

Prerequisite – Varargs , Method Overloading

Method Overloading in Varargs



Overloading allows different methods to have same name, but different signatures where signature can differ by number of input parameters or type of input parameters or both. We can overload a method that takes a variable-length argument by following ways:

Varargs and Ambiguity

Sometimes unexpected errors can result when overloading a method that takes a variable length argument. These errors involve ambiguity because both the methods are valid candidates for invocation. The compiler cannot decide onto which method to bind the method call.




// Java program to illustrate Varargs and ambiguity
class Test 
{
    // A method that takes varargs(here integers).
    static void fun(int ... a) 
    {
        System.out.print("fun(int ...): " +
                "Number of args: " + a.length +
                " Contents: ");
          
        // using for each loop to display contents of a
        for(int x : a)
            System.out.print(x + " ");
          
        System.out.println();
    }
      
    // A method that takes varargs(here booleans).
    static void fun(boolean ... a)
    {
        System.out.print("fun(boolean ...) " +
                "Number of args: " + a.length +
                " Contents: ");
          
        // using for each loop to display contents of a
        for(boolean x : a)
            System.out.print(x + " ");
          
        System.out.println();
    }
      
    public static void main(String args[])
    {
        // Calling overloaded fun() with different  parameter
        fun(1, 2, 3); //OK
        fun(true, false, false); //OK
        fun(); // Error: Ambiguous!
    }
}

In above program, the overloading of fun( ) is perfectly correct. However, this program will not compile because of the following call:

fun(); // Error: Ambiguous!

According to (JLS 15.2.2), there are 3 phases used in overload resolution: First phase performs overload resolution without permitting boxing or unboxing conversion, Second phase performs overload resolution while allowing boxing and unboxing and Third phase allows overloading to be combined with variable arity methods, boxing, and unboxing. If no applicable method is found during these phases, then ambiguity occurs.
The call above could be translated into a call to fun(int …) or fun(boolean …). Both are equally valid and do not be resolved after all three phases of overload resolution because both the data types are different. Thus, the call is inherently ambiguous.

Another example of ambiguity:
The following overloaded versions of fun( )are inherently ambiguous:

static void fun(int ... a) { // method body  }
static void fun(int n, int ... a) { //method body }

Here, although the parameter lists of fun( ) differ, there is no way for the compiler to resolve the following call:

fun(1)

This call may resolve to fun(int … a) or fun(int n, int … a) method, thus creating ambiguity. To solve these ambiguity errors like above, we will need to forego overloading and simply use two different method names.


Article Tags :