A variadic parameter accepts an arbitrary number of arguments and automatically collects them into an array at the call site. The convenience becomes dangerous when one argument is ambiguous or has the wrong declared type. section 2.9 section 2.15
One argument can change the meaning
For `static void printAll(Object... data)`, `printAll("Hello", "World")` and `printAll(new Object[]{"Hello", "World"})` produce the same array. However, `Object obj = new Object[]{"Hello", "World"}; printAll(obj);` wraps the array inside another array because compilation uses `obj`'s declared type, `Object`, rather than its runtime type. Passing `null` is also hazardous: `printAll(null)` supplies a null array reference and can cause a NullPointerException during iteration. section 2.9.1
static void printAll(Object... data) {
for (Object d : data) {
System.out.println(d);
}
}
Inspect the minimal `Object...` method to see that callers ultimately provide an array, whether the syntax is flat arguments or an explicit array. section 2.9.1
Collections are not expanded
A generic method such as `contains(T needle, T... haystack)` accepts separate values conveniently, but passing a `List<String>` does not expand the list. The compiler can infer `T` as `Object` and wrap the collection as one element, so the call compiles yet always returns false. Changing an array variable to a collection therefore requires checking every use, not only compiler errors. section 2.9.2
Reduce ambiguity and catch silent behavior changes:
- Cast deliberately when passing one null: use `(Object)null` for an array containing null, or `(Object[])null` for a null array reference. section 2.9.1
- Treat array-to-collection changes as semantic changes, and test boolean methods with both true and false cases. section 2.9.2
- Use IntelliJ IDEA's `Iterable Is Used as Vararg` inspection for collection arguments, while recognizing that static analyzers only warn about some ambiguous calls. section 2.9.2 section 2.9.1







