Java Varargs: Variable-Length Arguments with Examples
Introduction
How would you write a method which adds up two numbers - or three, or ten? Before Java 5, you had to write a separate overloaded methodClick to read tutorial: Method Overloading in Java with Examples for each count, or make callers wrap their values in an array. Varargs (variable-length arguments) let one method accept any number of arguments. This tutorial explains Java varargs with examples. We will start with the syntax, and see that a varargs parameter is really an array. We will then combine varargs with ordinary parameters, and look at the rules. Next we will see varargs in the Java library, including
(Note - Varargs parameters are arrays, so this tutorial builds on Java ArraysClick to read tutorial: Java Arrays Tutorial: Declare, Create and Initialize.) Syntax of varargs A varargs parameter is declared with three dots after its type -
Where,
OUTPUT of the above code
Explanation of the code
Varargs with other parameters
A method can have ordinary parameters as well as a varargs parameter, with these rules -
OUTPUT of the above code
OUTPUT on compiling the above code
Varargs in the Java library
You have already been using varargs methods -
OUTPUT of the above code
OUTPUT of the above code
Casting
2. Ambiguous overloads. Overloading two varargs methods - such as
3. Performance. Each call creates a new array. That cost is tiny, but in code called millions of times it adds up - which is why
printf() and List.of(). Lastly, we will go through the pitfalls - passing null, ambiguous overloads and performance.(Note - Varargs parameters are arrays, so this tutorial builds on Java ArraysClick to read tutorial: Java Arrays Tutorial: Declare, Create and Initialize.) Syntax of varargs A varargs parameter is declared with three dots after its type -
returnType methodName(Type... name)- the method can be called with zero or more arguments of
Type, separated by commas; - inside the method,
nameis an ordinary array -Type[]- holding the arguments, withname.lengthgiving how many were passed; - the caller can also pass an existing array instead of separate values.
A method with a varargs parameter
//SumVarargs.java
public class SumVarargs {
static int sum(int... numbers) {
System.out.print(" received " + numbers.length + " argument(s): ");
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
public static void main(String[] args) {
System.out.println(sum());
System.out.println(sum(5));
System.out.println(sum(1, 2, 3));
System.out.println(sum(10, 20, 30, 40, 50));
int[] scores = {72, 85, 90};
System.out.println(sum(scores)); // an existing array works too
}
}
received 0 argument(s): 0 received 1 argument(s): 5 received 3 argument(s): 6 received 5 argument(s): 150 received 3 argument(s): 247
- For each call, the compiler creates an array holding the arguments and passes it to
sum().sum(1, 2, 3)is compiled assum(new int[] {1, 2, 3}). - With no arguments,
numbersis an empty array - notnull- so the loop simply does not run, and the method returns 0. - Passing an existing array passes it directly, with no copy.
- The varargs parameter must be the last parameter.
- A method can have only one varargs parameter.
- Arguments are matched to the ordinary parameters first; all the remaining arguments go into the varargs array.
Combining ordinary and varargs parameters
//MixedParameters.java
public class MixedParameters {
static String joinWith(String separator, String... parts) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < parts.length; i++) {
if (i > 0) sb.append(separator);
sb.append(parts[i]);
}
return sb.toString();
}
static double max(double first, double... rest) { // at least one value is required
double max = first;
for (double d : rest) {
if (d > max) max = d;
}
return max;
}
public static void main(String[] args) {
System.out.println(joinWith(" | ", "Tom", "Harry", "Ethan"));
System.out.println(joinWith(", ", "only one"));
System.out.println("[" + joinWith("-") + "]");
System.out.println("max = " + max(3.5, 9.1, 2.7));
System.out.println("max = " + max(42));
}
}
Tom | Harry | Ethan only one [] max = 9.1 max = 42.0
max(double first, double... rest) is a useful pattern: making the first value a separate parameter means the method cannot be called with no values at all - max() would not compile. A plain double... values would have to handle an empty array at runtime.
Varargs must be the last parameter
//VarargsRules.java
public class VarargsRules {
static void log(String... messages, int level) {
}
}
VarargsRules.java:3: error: varargs parameter must be the last parameter
static void log(String... messages, int level) {
^
1 error
Varargs methods in the Java library
//LibraryVarargs.java
import java.util.Arrays;
import java.util.List;
public class LibraryVarargs {
public static void main(String[] args) {
System.out.printf("%s is %d and lives in %s%n", "Tom", 32, "London"); // printf(String, Object...)
String s = String.format("%d + %d = %d", 2, 3, 5); // format(String, Object...)
System.out.println(s);
List<String> cities = List.of("London", "Mumbai", "Tokyo"); // List.of(E...)
System.out.println(cities);
System.out.println(Arrays.asList(1, 2, 3)); // asList(T...)
System.out.println(String.join("/", "src", "main", "java")); // join(CharSequence, CharSequence...)
System.out.println(Math.max(4, 9)); // NOT varargs: exactly two values
}
}
Tom is 32 and lives in London 2 + 3 = 5 [London, Mumbai, Tokyo] [1, 2, 3] src/main/java 9
printf() and String.format() take Object..., which is how they accept any number of values of any type - the format specifiersClick to read tutorial: Java Console Output: println, printf and String.format say how to print each one. Math.max(), on the other hand, takes exactly two values; to find the maximum of many, you would write a varargs method like the one above.
Pitfalls
1. Passing null. A single null argument is passed as the array itself, so the parameter is null - not an array containing null.
Passing null to a varargs method
//VarargsNull.java
public class VarargsNull {
static void count(String... names) {
System.out.println(names == null ? "names is null" : "names has " + names.length + " element(s)");
}
public static void main(String[] args) {
count();
count("Tom", null);
count((String) null); // one null element
count((String[]) null); // a null array
}
}
names has 0 element(s) names has 2 element(s) names has 1 element(s) names is null
null tells the compiler which one you mean. A varargs method which may receive null should check for it before using the array.2. Ambiguous overloads. Overloading two varargs methods - such as
print(int... a) and print(long... a) - can make a call with no arguments ambiguous. Avoid overloading varargs methods, and remember that the compiler considers varargs methods only after every other overload has failed to match.3. Performance. Each call creates a new array. That cost is tiny, but in code called millions of times it adds up - which is why
List.of() has separate fixed-argument versions for up to ten elements, before falling back to varargs.
Summary
In this tutorial we first declared varargs parameters with Type..., and saw that inside the method they are ordinary arrays, empty when no arguments are passed. We then combined varargs with ordinary parameters, and learned the rules - only one varargs parameter, and it must be last - and the "at least one value" pattern. Next we recognized varargs in library methods such as printf(), String.format(), List.of() and String.join(). Lastly, we went through the pitfalls of passing null, ambiguous overloads and performance. In the next tutorial, we will look at methods which call themselves - recursionClick to read tutorial: Recursion in Java with Examples.Java Fundamentals Tutorials
Method Overloading in Java with ExamplesClick to read tutorial: Method Overloading in Java with Examples Recursion in Java with ExamplesClick to read tutorial: Recursion in Java with Examples Java Methods: Defining, Calling and Returning ValuesClick to read tutorial: Java Methods: Defining, Calling and Returning Values Is Java Pass-by-Value or Pass-by-Reference?Click to read tutorial: Is Java Pass-by-Value or Pass-by-Reference? Static vs Instance Methods in JavaClick to read tutorial: Static vs Instance Methods in Java What is Java? History, Features, Editions and UsesClick to read tutorial: What is Java? History, Features, Editions and Uses
Method Overloading in Java with ExamplesClick to read tutorial: Method Overloading in Java with Examples Recursion in Java with ExamplesClick to read tutorial: Recursion in Java with Examples Java Methods: Defining, Calling and Returning ValuesClick to read tutorial: Java Methods: Defining, Calling and Returning Values Is Java Pass-by-Value or Pass-by-Reference?Click to read tutorial: Is Java Pass-by-Value or Pass-by-Reference? Static vs Instance Methods in JavaClick to read tutorial: Static vs Instance Methods in Java What is Java? History, Features, Editions and UsesClick to read tutorial: What is Java? History, Features, Editions and Uses