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 | ||
---|---|---|
| ||
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 | ||
---|---|---|
| ||
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