This Tech Tip reprinted with permission by java.sun.com

Variable arity methods, sometimes referred to as varargs methods, accept an arbitrary set of arguments. Prior to JDK 5.0, if you wanted to pass an arbitrary set of arguments to a method, you needed to pass an array of objects. Furthermore, you couldn't use variable argument lists with methods such as the format method of the MessageFormat class or the new to JDK 5.0 printf method of PrintStream to add additional arguments for each formatting string present.

JDK 5.0 adds a varargs facility that's a lot more flexible. To explore the varargs facility, let's look at a JDK 5.0 version of one of the printf methods in the PrintStream class:

  public PrintStream printf(String format,
                             Object... args)

Essentially, the first argument is a string, with place holders filled in by the arguments that follow. The three dots in the second argument indicate that the final argument may be passed as an array or as a sequence of arguments. Note that the three dots are similar to how variable argument lists are specified in C and C++ programming.

The number of place holders in the formatting string determines how many arguments there need to be. For example, with the formatting string "Hello, %1s\nToday is %2$tB %2$te, %2$tY" you would provide two arguments: the first argument of type string, and the second of type date. Here's an example:

  import java.util.*;

   public class Today {
     public static void main(String args[]) {
       System.out.printf(
         "Hello, %1s%nToday is %2$tB %2$te, %2$tY%n",
         args[0], new Date());
     }
   }

Provided that you pass in an argument for the name, the results would be something like the following:

  > java Today Ed
   Hello, Ed
   Today is October 18, 2005

Autoboxing and unboxing allow you to provide primitive type arguments (as in the following printf method):

System.out.printf("Pi is approximately  %f", Math.PI, %n);

Here, Math.PI is of type double. Autoboxing converts it to an object of type Double. (For more information on autoboxing, see the April 5, 2005 tip Introduction to Autoboxing).

If you create your own methods to accept variable argument lists, only the last argument to the method can be declared as accepting a variable list. You can't put the variable-length argument first. For example, the following method declaration is valid -- it defines a method that has one parameter which accepts a variable number of String arguments:

 private static void method1(String... args)

The variable argument parameter doesn't have to be the only argument. For instance, the following method takes one integer argument followed by an arbitrary number of arguments.

 private static void method2(int arg, Object... args) {

Putting methods that have the two formats shown above into a sample class allows you to call the methods with a different number of arguments:

   method1("Hello", "World");
      method1(args);
      method2(12, 'a', "Hello", Math.PI, 1/3.0);
      method2(18, 94.0);

The last call shown above is slightly different than the others. It takes the String[] argument that comes into the main() method. Because the varargs facility is just implicit syntax for creating and passing arrays, an array can be passed directly. In this case, the compiler will simply pass the array unmodified.

Here's a sample class, MyArgs, that includes the two types of methods:

  import java.util.*;

   public class MyArgs {
     public static void main(String args[]) {
       method1(12, 'a', "Hello", Math.PI, 1/3.0);
       method1(18, 94.0);
       method2("Hello", "World");
       method2(args);
     }

     private static void method1(int arg, Object... args) {
       System.out.println(Arrays.asList(args) + " / " + arg);
     }

     private static void method2(String... args) {
       System.out.println(Arrays.asList(args) + 
         " // " + args.length);
     }
   }

Here's a sample run of MyArgs:

 > java MyArgs x y z

  [a, Hello, 3.141592653589793, 0.3333333333333333] / 12
  [94.0] / 18
  [Hello, World] // 2
  [x, y, z] // 3

MyArgs accesses the variable argument list by passing it to the Arrays.asList() method. In other words, the argument is accessed just like an array. Normally, you would do something more like the following in an enhanced for loop:

 for (String arg: args) {
    ...
  }

This would allow you to process one element at a time.

As you can see, without much programming effort, the varargs feature allows you to define methods that accept a variable number of arguments. For more information about varargs, see Varargs.

Copyright (c) 2004-2005 Sun Microsystems, Inc.
All Rights Reserved.