You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 33 Next »

The varargs feature was introduced in the JDK v1.5.0 to support methods that accept variable numbers of arguments.

According to the Java SE 6 documentation [[Sun 2006]] and varargs

As an API designer, you should use [varargs 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

Overloading varargs methods creates confusion, as shown in this noncompliant code example. Which definition of doSomething() gets invoked?

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

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

When run, this program outputs:

Overloaded method invoked

because the non-varargs definition is more specific, and consequently a better fit for the arguments given. However, this degree of confusion is best avoided when possible.

Compliant Solution

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

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

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

Exceptions

DCL08-EX1: It may be desirable to violate this guideline for performance reasons. One such reason would be to avoid the cost of creation of an array instance and its initialization 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) { }

It is important, when overloading varargs methods, to avoid any ambiguity as to which method would be invoked. The idiom shown above avoids the pitfalls of incorrect method selection by using unambiguous method signatures.

Risk Assessment

Unmindful use of the varargs feature may create ambiguity and diminish code readability.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

DCL08-J

low

unlikely

medium

P2

L3

Automated Detection

Automated detection is straightforward.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

Bibliography

[[Bloch 2008]] Item 42: "Use varargs judiciously"
[[Steinberg 2005]] "Using the Varargs Language Feature"
[[Sun 2006]] varargs


DCL07-J. Beware of integer literals beginning with '0'      03. Declarations and Initialization (DCL)      DCL09-J. Enable compile-time type checking of varargs types

  • No labels