A variable arity (aka varargs) method is a method that can take a variable number of arguments. The method must contain at least one fixed argument. When processing a variable arity method call, the Java compiler checks the types of all arguments, and all of the variable actual arguments must match the variable formal argument type. However, compile-time type checking is ineffective when Object
or generic parameter types are used [Bloch 2008]. The presence of initial parameters of specific types is irrelevant; the compiler will remain unable to check Object
or generic variable parameter types. Enable strong compile-time type checking of variable arity methods by using the most specific type possible for the type of the method parameter.
Noncompliant Code Example (Object
)
This noncompliant code example sums a set of numbers using a variable arity method using Object
. It that uses Object
as the variable arity type. Consequently, this method accepts an arbitrary mix of parameters of any object type. Legitimate uses of such declarations are rare (but see the "Applicability" section of this guideline).
Code Block | ||
---|---|---|
| ||
double sum(Object... args) { double result = 0.0; for (Object arg : args) { if (arg instanceof Byte) { result += ((Byte) arg).byteValue(); } else if (arg instanceof Short) { result += ((Short) arg).shortValue(); } else if (arg instanceof Integer) { result += ((Integer) arg).intValue(); } else if (arg instanceof Long) { result += ((Long) arg).longValue(); } else if (arg instanceof Float) { result += ((Float) arg).floatValue(); } else if (arg instanceof Double) { result += ((Double) arg).doubleValue(); } else { throw new ClassCastException(); } } return result; } |
Compliant Solution (Number
)
This compliant solution defines the same method but uses the Number
type. This abstract class is general enough to encompass all numeric types, yet specific enough to exclude nonnumeric types.
Code Block | ||
---|---|---|
| ||
double sum(Number... args) {
// ...
} |
Noncompliant Code Example (Generic Type)
...
Code Block | ||
---|---|---|
| ||
<T> double sum(T... args) {
// ...
} |
Compliant Solution (Number
)
...
. |
...
Code Block | ||
---|---|---|
| ||
double sum(Number... args) { // ... } |
Compliant Solution (Generic Type)
...
Variable arity signatures using Object
and imprecise generic types are acceptable when the body of the method lacks both casts and autoboxing and it also compiles without error. Consider the following example, which operates correctly for all object types and type-checks successfully:
...
Item 42, "Use Varargs Judiciously" | |
"Using the Varargs Language Feature" | |
...