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 Object
or generic T
parameter types are used [java:[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. Legitimate uses of such declarations are rare. (See exception below).
ReturnType method(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, legitimate uses of such declarations are rare.
<T> ReturnType method(T... args) { }
Compliant Solution
Be as specific as possible when declaring parameter types; avoid Object
and imprecise generic types in varargs.
ReturnType method(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 [java:[Bloch 2008]].
Also, note that autoboxing does not allow strong compile-time type checking of primitive types and their corresponding wrapper classes.
Exceptions
DCL03-EX0: Varargs signatures using Object
and imprecise generic types are acceptable when the body of the method does not use casts or auto-boxing and 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 prevents strong compile-time type checking, creates ambiguity, and diminishes code readability.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
DCL03-J |
low |
unlikely |
medium |
P2 |
L3 |
Automated Detection
Automated detection appears to be straightforward.
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="22b205a7-793e-4777-a3f3-5eba9eda4350"><ac:plain-text-body><![CDATA[ |
[java:[Bloch 2008 |
AA. Bibliography#Bloch 08]] |
Item 42: "Use Varargs Judiciously" |
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="36ddb617-c10e-4319-bb56-8cefc459d09e"><ac:plain-text-body><![CDATA[ |
[java:[Steinberg 2005 |
AA. Bibliography#Steinberg 05]] |
"Using the Varargs Language Feature" |
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1a4c9468-4fdd-4b19-b66f-a547009dc327"><ac:plain-text-body><![CDATA[ |
[java:[Sun 2006 |
AA. Bibliography#Sun 06]] |
[varargs |
http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html] |
]]></ac:plain-text-body></ac:structured-macro> |
DCL02-J. Avoid ambiguous overloading of varargs methods 01. Declarations and Initialization (DCL) DCL04-J. Do not derive a value associated with an enum from its ordinal