Home Java Understanding Java Variable Length Arguments (VarArgs)

Understanding Java Variable Length Arguments (VarArgs)

0
543
Java Variable Length Arguments
Java Variable Length Arguments

With the release of JDK 5, Java included a new feature that helped in simplifying the method creation which require or need to take a variable number of arguments. This feature is called varargs and it is short for variable-length arguments. In this journal entry, we will try to understand java variable length arguments (varargs).

Situations that require that a variable number of arguments be passed to a method are not unusual. For example, the printf( ) method that is part of Java’s I/O library.

PrintStream printf(String fmtString, Object … args)
PrintStream printf(Locale loc, String fmtString, Object … args)

The first version writes args to standard output in the format specified by fmtString, using the default locale. The second lets you specify a locale. Given below are the sample printf( ) statements:

System.out.printf("Various integer formats: ");
System.out.printf("%d %(d %+d %05d\n", 3, -3, 3, 3);

Prior to JDK 5, variable-length arguments could be handled two ways. First, if we know before hand that the number of arguments are few, then we can simply create the overloaded version of the methods to handle this situation. Although this works and is suitable for some cases, it applies to only a narrow class of situations.

In the second approach, when the number of arguments are large or unknowable, the variables are stored in an array. This array is then passed onto the method.

In cases where the maximum number of potential arguments was larger, or unknowable, a second approach was used in which the arguments were put into an array, and then the array was passed to the method. This approach is illustrated by the following program:

// Use an array to pass a variable number of
// arguments to a method. This is the old-style
// approach to variable-length arguments.
class PassArray {
  static void djTest(int v[]) {
    System.out.print("Number of args: " + v.length + " Contents: ");
    for(int x : v)
      System.out.print(x + " ");
    System.out.println();
  }
  public static void main(String args[])
  {
    // Notice how an array must be created to
    // hold the arguments.
    int n1[] = { 10 };
    int n2[] = { 1, 2, 3 };
    int n3[] = { };
    djTest(n1); // 1 arg
    djTest(n2); // 3 args
    djTest(n3); // no args
  }
}

The output from the program is shown here:
Number of args: 1 Contents: 10
Number of args: 3 Contents: 1 2 3
Number of args: 0 Contents:

This approach is not only tedious but error-prone also. To handle this in a simpler approach, the feature varargs – also known as variable length arguments can be used.

Varargs is specified by three periods (…). The syntax for implementing varargs is as follows:

accessModifier methodName(datatype ... args) { 
  // METHOD BODY 
}

The above syntax tells the compiler that methodName( ) can be called with zero or more arguments. As a result, args is implicitly declared as an array of type datattype[ ]. Thus, inside methodName( ), args is accessed using the normal array syntax. Here is the preceding program rewritten using a vararg:

// Demonstrate variable-length arguments.
class VarArgs {
  // djTest() now uses a vararg.
  static void djTest(int ... v) {
    System.out.print("Number of args: " + v.length + " Contents: ");
    for(int x : v)
      System.out.print(x + " ");
    System.out.println();
  }

  public static void main(String args[])
  {
    // Notice how vaTest() can be called with a
    // variable number of arguments.
    djTest(10); // 1 arg
    djTest(1, 2, 3); // 3 args
    djTest(); // no args
  }
}

The output of the above program is exactly the same as the above program.

There are few points you should also keep in mind while writing methods using varargs feature.

Point #1: The variable-length parameter must be the last parameter declared by the method. For example, this method declaration is perfectly acceptable:

int doIt(int a, int b, double c, int ... vals)   // OK!

The below declaration is unacceptable.

int doIt(int a, int b, double c, int ... vals, int afterVarags)  // ERROR!

Point #2: There must be only one varargs parameter. For example, this declaration is also invalid:

int doIt(int a, int b, double c, int ... vals, int ... afterVarags)  // ERROR!

 

Recommended Read:

Overloading Vararg Methods

You can overload a method that takes a variable-length argument. For example, the following program overloads djTest( ) three times:

//METHOD ACCEPTING INTEGER PARAMETERS
void djTest(int ... a)

//METHOD ACCEPTING BOOLEAN PARAMETERS
void djTest(bool ... b)

//METHOD ACCEPTING A NORMAL PARAMETER AND INTEGER VARARGS
void djTest(String msg, int ... a)

Varargs and Ambiguity

Using variable length arguments in method overloading can sometimes throw unexpected errors. Below is one of the most common error that can happen while using method overloading with variable length arguments.

//METHOD WITH VARIABLE LENGTH ARGUMENT
int djTest(int .... args)

//METHOD WITH NORMAL PARAMETER AND VARIABLE LENGTH ARGUMENT
int djTest(int i, int ... args)

The above-mentioned method djTest( ) is using the overloading functionality but the call of this function involve ambiguity. Although the parameter lists of djTest( ) differ, there is no way for the compiler to resolve the following call:

djTest(1)

The above function call can translate into djTest(1) with one varargs argument, or into a call of djTest(int, int…) with no varargs argument. There is no way that the compiler can identify which function to call. Thus, the situation is ambiguous. Because of ambiguity errors like the one just shown, sometimes you have to forego overloading functionality and simply use two different method names.

Conclusion

The use of varargs – variable length argument helps in simplifying the creation of methods that need to take a variable number of arguments. However, the following points should always be in your mind while designing your method.

  • Prior to JDK 5, variable length arguments could be handled in two ways: One was using overloading, other was using array argument.
  • Vararg Methods can also be overloaded but overloading may lead to ambiguity.
  • There can be only one variable argument in a method.
  • Variable argument (varargs) must be the last argument.