Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Wiki Markup
The Java compiler type-checks the arguments to a varargs method to ensure that they are of the same type or object reference. However, the compile-time checking is ineffective when two method signatures are used in particular - {{Object}} and the generic type {{T}} \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. Another requirement for providing strong compile-time type checking of variable argument methods is to be as specific as possible when declaring the type of the method parameter.

Noncompliant Code Example

This noncompliant code example declares two varargs methods, one with an Object parameter and another with a generic type T. Both these approaches are flawed as they break strong compile-time type checking. As written, the first accepts an arbitrary mix of parameters of any object type; the second accepts a variable number of parameters that are all of the same object type. Although such declarations have legitimate uses (see exception below), those uses rarely arise; avoid use of such declarations in general.

Code Block
bgColor#FFCCCC
ReturnType1 suspect1(Object... args) { }
<T> ReturnType2 suspect2(T... args) { }

Compliant Solution

Do not use generic types like Object in varargs and be Be as specific as possible when declaring parameter types; avoid Object and imprecise generic types in varargs.

Code Block
bgColor#ccccff
ReturnType1 specific1(primitiveType1somePrimitiveType1... args) { } // int, or whatever
ReturnType2 specific2(primitiveType2SpecificObjectType2... args) { }

Wiki Markup
Retrofitting old methods containing {{final}} array parameters with generically typed varargs is not always a good idea. This is because if some method did not accept an argument of a particular type, it may be possible to override the compile-time checking so that with the use of generic varargs, it now compiles cleanly \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. 

Also, note that autoboxing does not allow strong compile time type checking of primitive types and their corresponding wrapper classes.

Exceptions

DCL09-EX1: Varargs signatures using Object and imprecise generic types are acceptable when, and only when, the body of the method uses no casts or auto-boxing, and compiles without error. For example:

Code Block

Collection<T> assembleCollection(T... args) {
  Collection<T> result = new HashSet<T>();
  // add each argument to the result collection
  return result;
}

operates correctly for all object types and type-checks successfully.

Risk Assessment

Unmindful use of the varargs feature breaks strong compile-time type checking, creates ambiguity and diminishes code readability.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

DCL09-J

low

unlikely

medium

P2

L3

Automated Detection

TODOAutomated detection appears to be straightforward.

Related Vulnerabilities

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

Bibliography

Wiki Markup
\[[Sun 2006|AA. Bibliography#Sun 06]\] [varargs|http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html] 
\[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 42: "Use varargs judiciously"
\[[Steinberg 2005|AA. Bibliography#Steinberg 05]\] "Using the Varargs Language Feature"
\[[Sun 2006|AA. Bibliography#Sun 06]\] [varargs|http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html] 

...

DCL08-J. Avoid overloading varargs methods      03. Declarations and Initialization (DCL)      DCL10-J. Ensure proper initialization by declaring class and instance variables final