Varargs
- accept zero or more arguments
- an anonymous array is created every time
Don’t use Varargs unless really needed
- in most cases, we can just use a collection/list then wrap the hard-coded values with
Arrays.asList
Require one
static int min(int firstArg, int... remainingArgs)
Good Cases to Use Varargs
- Reflection uses lot of variable argument method.
public Method java.lang.Class.getMethod(String name, Class<?>... parameterTypes)
Performance-critical Methods
- an anonymous array is created every time
ImmutableList.of(), of(e1), of(e1, e2), of(e1,e2,,,, e11), 0f(e1,,,e1, E... others)
Careful when Overloading with Varargs
static void method(int ... a) {}
static void method(int first, int ... a) {}
// compile error: ambiguous method call, both matches
method(1);
The correct way is to:
Careful when Overloading with Varargs and Autoboxing
static void method(int ... a) {}
static void method(Integer ... a) {}
// compile error: ambiguous method call, both matches
method(1);
Java Generic and Array doesn’t mix well
Item 32: Combine generics and varargs judiciously
- A generic varargs parameter is useful in some cases.
Arrays.asList(T... a)
,Collections.addAll(Collection<? super T> c, T... elements)
,EnumSet.of(E first, E... rest)
.
- but it also may be dangerous: throw ClassCastException at runtime etc
// Mixing generics and varargs can violate type safety!
static void dangerous(List<String>... stringLists) {
List<Integer> intList = List.of(42);
Object[] objects = stringLists;
objects[0] = intList; // Heap pollution
String s = stringLists[0].get(0); // ClassCastException
}
Varargs gotchas: passing an array, a collection into varargs
public static String ezFormat(Object... args) {
String format = new String(new char[args.length]).replace("\0", "[ %s ]");
return String.format(format, args);
}
int[] myNumbers = { 1, 2, 3 };
// [ [I@7852e922 ]
System.out.println(ezFormat(myNumbers));
// [ [I@4e25154f ]
System.out.println(ezFormat(new int[] { 1, 2, 3 }));
- Passing an iterable to the varargs method containsExactly(Object…) is often not the correct thing to do.
@SafeVarargs
- a promise by the author of a method that it is typesafe, thus the compiler doesn’t warn.