Variable arguments
Sometimes you do not know in advance how many arguments a method will get: the sum of two numbers, five, or none. For such cases Java has varargs — a parameter that accepts any number of values of one type.
Declaring varargs
Put an ellipsis ... after the parameter type. In a call, list the arguments separated by commas — as many as you like:
int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
void main() {
IO.println(sum(1, 2));
IO.println(sum(1, 2, 3, 4, 5));
IO.println(sum());
}Output:
3
15
0Java collects the passed values into an array itself, so the calling code does not have to create one.
It is an array inside
Inside the method a varargs parameter is a regular array. It has a length and index access:
void printInfo(String... names) {
IO.println("Count: " + names.length);
if (names.length > 0) {
IO.println("First: " + names[0]);
}
}
void main() {
printInfo("Anna", "Oleg", "Maria");
printInfo();
}Output:
Count: 3
First: Anna
Count: 0With no arguments the method gets an empty array, not "nothing", so names.length safely returns 0.
Passing an array
Instead of a list of arguments you can pass a ready array — Java takes it as is:
int max(int... values) {
int best = values[0];
for (int v : values) {
if (v > best) {
best = v;
}
}
return best;
}
void main() {
int[] prices = {12, 45, 7};
IO.println(max(prices));
IO.println(max(3, 9, 4));
}Output:
45
9Together with regular parameters
Varargs can be combined with regular parameters, but it must come last. The regular parameters are filled first, and the remaining arguments go into the array:
void order(String customer, String... items) {
IO.println(customer + " orders " + items.length + " items: " + String.join(", ", items));
}
void main() {
order("Anna", "latte", "croissant");
}Output:
Anna orders 2 items: latte, croissantString.join() is itself a varargs method: it joins strings with a separator.
printf
The System.out.printf() method also takes a variable number of arguments. The first one is a template where %s marks a place for a string, %d for a whole number and %n a line break:
void main() {
System.out.printf("%s bought %d books%n", "Oleg", 3);
}Output:
Oleg bought 3 booksIf there are fewer values after the template than specifiers, you get an error at run time; extra values are simply ignored.
Formatting is covered in more detail in the lesson on text blocks and formatting.
Common mistake
There can be only one varargs parameter, and only at the end of the list. Otherwise Java cannot tell where its arguments end:
void order(String... items, String customer) {
IO.println(customer);
}
void main() {
order("latte", "Anna");
}Output:
Main.java:1: error: varargs parameter must be the last parameter
void order(String... items, String customer) {
^
1 error
error: compilation failedMove varargs to the end: order(String customer, String... items).