The Java compiler type-checks the arguments to each varargs method to ensure that the arguments are of the same type or object reference. However, the compile-time checking is ineffective when two specific parameter types are used: Object
and the generic type T
[[Bloch 2008]]. 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 (Object
)
This noncompliant code example declares a vararg method using Object
. It accepts an arbitrary mix of parameters of any object type. Although such declarations have legitimate uses (see exception below), those uses rarely arise.
ReturnType function(Object... args) { }
Noncompliant Code Example (generic type)
This noncompliant code example declares a vararg method using a generic type parameter. It accepts a variable number of parameters that are all of the same object type. Again, although such declarations have legitimate uses, those uses rarely arise.
<T> ReturnType function(T... args) { }
Compliant Solution
Be as specific as possible when declaring parameter types; avoid Object
and imprecise generic types in varargs.
ReturnType function(SpecificObjectType... args) { }
Retrofitting old methods containing final array parameters with generically-typed varargs is not always a good idea. For example, given a method that does not accept an argument of a particular type, it could be possible to override the compile-time checking — through the use of generic varargs parameters — so that the method would compile cleanly rather than correctly causing a compile-time error.[[Bloch 2008]].
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 only acceptable when the body of the method both uses no casts or auto-boxing, and also compiles without error. Consider the following example, which operates correctly for all object types and type-checks successfully.
Collection<T> assembleCollection(T... args) { Collection<T> result = new HashSet<T>(); // add each argument to the result collection return result; }
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
Automated detection appears to be 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
DCL08-J. Avoid overloading varargs methods 03. Declarations and Initialization (DCL) DCL10-J. Ensure proper initialization by declaring class and instance variables final