Skip to end of metadata
Go to start of metadata

The variable arity (varargs) feature was introduced in JDK v1.5.0 to support methods that accept a variable numbers of arguments.

According to the Java SE 6 documentation [Oracle 2011b],

As an API designer, you should use [variable arity methods] sparingly, only when the benefit is truly compelling. Generally speaking, you should not overload a varargs method, or it will be difficult for programmers to figure out which overloading gets called.

Noncompliant Code Example

In this noncompliant code example, overloading variable arity methods makes it unclear which definition of displayBooleans() is invoked:

class Varargs {
  private static void displayBooleans(boolean... bool) {
    System.out.print("Number of arguments: " + bool.length + ", Contents: ");

    for (boolean b : bool)
      System.out.print("[" + b + "]");
  } 
  private static void displayBooleans(boolean bool1, boolean bool2) {
    System.out.println("Overloaded method invoked");  
  }
  public static void main(String[] args) {
    displayBooleans(true, false);
  }
}

When run, this program outputs

Overloaded method invoked

because the nonvariable arity definition is more specific and consequently a better fit for the provided arguments. However, this complexity is best avoided.

Compliant Solution

To avoid overloading variable arity methods, use distinct method names to ensure that the intended method is invoked, as shown in this compliant solution:

class Varargs {
  private static void displayManyBooleans(boolean... bool) {
    System.out.print("Number of arguments: " + bool.length + ", Contents: ");

    for (boolean b : bool)
      System.out.print("[" + b + "]");
  } 
  private static void displayTwoBooleans(boolean bool1, boolean bool2) {
    System.out.println("Overloaded method invoked");  
    System.out.println("Contents: [" + bool1 + "], [" + bool2 + "]");  
  }
  public static void main(String[] args) {
    displayManyBooleans(true, false);
  }
}

Applicability

Injudicious use of overloaded variable arity methods may create ambiguity and diminish code readability.

It may be desirable to violate this rule for performance reasons. One such reason would be to avoid the cost of creating an array instance and initializing it on every invocation of a method [Bloch 2008].

public void foo() { }
public void foo(int a1) { }
public void foo(int a1, int a2, int... rest) { }

When overloading variable arity methods, it is important to avoid any ambiguity regarding which method should be invoked. The preceding code sample avoids the possibility of incorrect method selection by using unambiguous method signatures.

Automated detection is straightforward.

Bibliography

[Bloch 2008]

Item 42, "Use Varargs Judiciously"

[Steinberg 2008]

"Using the Varargs Language Feature"

[Oracle 2011b]

varargs

 


1 Comment

  1. Kinda academic, but this rule belongs in the Methods section (at least with the other rules about overloading methods).