Varargs in Java
Type... args, must be last, received as an array.
The three dots
A varargs parameter, written Type... name, lets callers pass zero or more arguments of that type. Inside the method it's simply an array: nums.length, nums[0] and for-each all work.
static int sum(int... nums) {
int total = 0;
for (int n : nums) total += n;
return total;
}Your turn
What prints?
static int total(int... n) {
int t = 0;
for (int x : n) t += x;
return t;
}
void main() {
System.out.println(total());
System.out.println(total(4, 5, 6));
}0 15Compile errornull 15
Show the answer
Calling with no arguments is legal: Java passes an empty array (length 0), never null. So the loop runs zero times and returns 0. Three arguments become an array of length 3.
Three ways to call
Callers can pass nothing (an empty array arrives), several values (Java packs them into a new array), or an existing array (used directly as the varargs array).
sum(); // nums = {}
sum(1, 2); // nums = {1, 2}
sum(new int[]{4, 5}); // that arrayYour turn
What prints?
static void show(String... xs) {
System.out.println(xs.length);
}
void main() {
show(new String[]{"a", "b", "c"});
show("solo");
}3 11 13 3
Show the answer
The String[] passed directly is the varargs array (length 3). The single value "solo" is wrapped into a new array of length 1.
Zero means zero
Varargs means zero or more. If the method blindly reads xs[0], then first() compiles fine and throws ArrayIndexOutOfBoundsException at runtime. Handle the empty case, or require one normal parameter first.
static int first(int... xs) {
return xs[0]; // boom when empty
}
// safer: at least one is required
static int max(int first, int... rest)Where the dots may go
void log(Object... args, String level)
void log(int... a, String... b)Varargs must be the LAST parameter, and there can be only one: otherwise Java can't tell where the variable part ends.
void log(String level, Object... args)Fixed parameters first, then a single varargs at the end.
In real projects
You use varargs daily: printf, String.format, List.of(...), Arrays.asList(...). Remember from overloading that varargs are tried last. And creating that array costs a little, which is why List.of has separate overloads for 0 to 10 elements and only falls back to varargs beyond that.
Key takeaways
- int... nums arrives inside the method as an int[]
- Callers can pass nothing, several values, or an existing array
- Only one varargs parameter, and it must come last
- Overload resolution tries varargs methods last
Varargs arrived in Java 5 (2004), and static void main(String... args) is a perfectly valid way to write a classic main method.
Practice questions
What does this print?
static int count(String... words) {
return words.length;
}
void main() {
System.out.println(count());
System.out.println(count("a", "b", "c"));
}- 1 3
- Compile error
- 0 3
- null 3
Check your answer
0 3. With no arguments, Java passes an empty array (length 0), never null. Three arguments become an array of length 3.
Which declaration compiles?
- static void log(Object... args, String level)
- static void log(String level, Object... args)
- static void log(int... a, String... b)
Check your answer
static void log(String level, Object... args). The varargs parameter must be last, and there can be only one. Otherwise the compiler couldn't tell where the variable part of the arguments ends.