When do you use varargs in Java?

I use varargs frequently for outputting to the logs for purposes of debugging.

Pretty much every class in my app has a method debugPrint():

private void debugPrint(Object... msg) {
    for (Object item : msg) System.out.print(item);
    System.out.println();
}

Then, within methods of the class, I have calls like the following:

debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
    serialNo, ", the grade is ", grade);

When I'm satisfied that my code is working, I comment out the code in the debugPrint() method so that the logs will not contain too much extraneous and unwanted information, but I can leave the individual calls to debugPrint() uncommented. Later, if I find a bug, I just uncomment the debugPrint() code, and all my calls to debugPrint() are reactivated.

Of course, I could just as easily eschew varargs and do the following instead:

private void debugPrint(String msg) {
    System.out.println(msg);
}

debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
    + serialNo + ", the grade is " + grade);

However, in this case, when I comment out the debugPrint() code, the server still has to go through the trouble of concatenating all the variables in every call to debugPrint(), even though nothing is done with the resulting string. If I use varargs, however, the server only has to put them in an array before it realizes that it doesn't need them. Lots of time is saved.


A good rule of thumb would be:

"Use varargs for any method (or constructor) that needs an array of T (whatever type T may be) as input".

That will make calls to these methods easier (no need to do new T[]{...}).

You could extend this rule to include methods with a List<T> argument, provided that this argument is for input only (ie, the list is not modified by the method).

Additionally, I would refrain from using f(Object... args) because its slips towards a programming way with unclear APIs.

In terms of examples, I have used it in DesignGridLayout, where I can add several JComponents in one call:

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

In the code above the add() method is defined as add(JComponent... components).

Finally, the implementation of such methods must take care of the fact that it may be called with an empty vararg! If you want to impose at least one argument, then you have to use an ugly trick such as:

void f(T arg1, T... args) {...}

I consider this trick ugly because the implementation of the method will be less straightforward than having just T... args in its arguments list.

Hopes this helps clarifying the point about varargs.


Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String.format. The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.

String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);