Varargs or Variable Arguments in Java

Java 5 introduced varargs or variable argument capability to methods. With this new syntax, it is possible for methods to accept variable number of arguments. Basically if a method accepts variable arguments, then you can pass zero arguments to that method, or you can send ten arguments to that method or even a hundred.

varargs-java

Varargs Syntax

The basic syntax of variable argument uses an ellipsis i.e. three dots after the data type. Lets see the syntax with an example,

void display(String... vals) {
//some code here
}

As you can see, The syntax of variable arguments is very simple. The data type is followed by three dots and then the identifier i.e. parameter name (vals in the example above). Inside the method body, the vararg is used as a normal array. So if you want to display all the values passed to our display method, you can implement it like this,

void display(String... vals) {
for(int i = 0; i < vals.length; i++) {
System.out.println(vals[i]);
}
}

You may have already noticed that vals acted just like an array.

Calling a Method That Takes Varargs

Now the question is how to call a method that takes variable number of arguments? Basically, you can call it with any number (zero or more) of arguments.

Our example method can be called with any number of Strings as arguments,

class VarargExp {
    void display(String... vals) {
        for(int i = 0; i < vals.length; i++) {
            System.out.println(vals[i]);
        }
    }
    public static void main(String[] args) {
        VarargExp ve = new VarargExp();
        ve.display("Hello");               //1 argument
        ve.display("are","you","there?");  //3 arguments
        ve.display();                      //no argument

        String[] arr = new String[]{"this","is","great"};
        ve.display(arr);
    }
}

In the code above, the first three calls to the display method are simple, we call it with one, three and no arguments. When we pass no argument, then vals in display method will act like an array of 0 size i.e. an empty array.

The last call to display might look a little strange. We are passing a String array to the display method. The compiler will gladly let this pass. As we’ve seen that the variable argument actually acts as an array, so the array that we passed will directly get passed to the display method. So vals in display method will contain three values i.e. “this”,”is” and “great”.

More Fun With Varargs

Since vararg acts like an array, you can have a main method with vararg,

class VarargMain {
    public static void main(String... args) {
        System.out.println("It worked!!");
    }
}

You can compile and run this code without any problems. Basically a method which takes String... and another method which takes String[] are more or less the same. The only difference is in calling the method. Calling the method which takes String[] requires that you pass the method a String[], calling the method which takes String... as argument is more flexible.

The vararg method gladly accepts any number of parameters and an array itself of the same data type (as we say in the last call to display in a previous example). Since String[] and String... are more or less the same, you can’t overload on these. So the following code will fail to compile,

class VarargExp {
    void display(String... vals) {
        //some code
    }
    void display(String[] strs) {
        //some code
    }
}

The above code will not compile because we can’t overload display method with String... and String[]. Also, a method can have only one vararg and that must be the last argument. So both of the methods given below will fail to compile,

void method1(String... vals, int... arr) {
}
void method2(String... vals, int i) {
}

method1 has two varargs which is not allowed. Vararg is not the last argument in method2, so it will also fail to compile.

Overloading with varargs can be a little tricky at times. There are some situations where the compiler is not able to resolve which method we are calling. Some cases might be counter intuitive and might be fixed in the future release of Java. Look at the following code,

class VarargExp {
    void display(int... vals) {
        for(int i = 0; i < vals.length; i++) {
            System.out.println(vals[i]);
        }
    }
    void display(double... vals) {
        for(int i = 0; i < vals.length; i++) {
            System.out.println(vals[i]);
        }
    }
    public static void main(String[] args) {
        VarargExp ve = new VarargExp();
        ve.display(10, 20, 30);
        ve.display(10.0, 20.0, 30.0);
    }
}

Here you’d say that the first call to display will call the int... version of display method and second call will call the double... version of display method. But the first call to display method is flagged as ambiguous by the compiler. This problem can be solved if we use an int array, but that defeats the whole purpose of vararg. Instead of calling display as ve.display(10, 20, 30); if we call it as ve.display(new int[]{10, 20, 30});, then the compiler will be able to match the call to display method with the int... version of the method.

You can even mix vararg with arrays. We can have a method which takes String[]... as argument (vararg before array is not allowed, so String...[] is an invalid syntax). As we know vararg is like array, so String[]... is similar to String[][]. So we can call such a method with any number of 1D String arrays. Lets see an example,

class VarargExp {
    void display(String[]... vals) {
        for(int i = 0; i < vals.length; i++) {
           for(int j = 0; j < vals[i].length; j++) {
            System.out.println(vals[i][j]);
           }
           System.out.println("-------------");
        }
    }
    public static void main(String[] args) {
        VarargExp ve = new VarargExp();
        String[] strs1 = new String[]{"hey","there"};
        String[] strs2 = new String[]{"hi","there"};
        ve.display(strs1, strs2);
    }
}

As you can see, we called display method with two 1D String arrays. We won’t go into much details about mixing array and vararg as this isn’t something anyone is likely to face daily.

Leave a Comment