Varargs (variable arguments) allow a method to accept a variable number of arguments. This means that you can pass zero or more arguments to a method without the need to overload the method multiple times with different numbers of parameters. Varargs provide flexibility when you’re not sure how many arguments you’ll need to pass to a method.
To declare a method that accepts varargs, you use an ellipsis (...
) after the data type of the parameter. Internally, Java treats varargs as an array.
The syntax for varargs is simple. The ellipsis (...
) is used after the data type to indicate that the method can accept a variable number of arguments:
public void methodName(DataType... varName) {
// method body
}
For example, to create a method that accepts a variable number of integers:
public void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}
In this example, the printNumbers()
method can take any number of int
values as its argument.
public class VarargsExample {
// Method that accepts variable number of integer arguments
public static void sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
System.out.println("Sum: " + total);
}
public static void main(String[] args) {
sum(1, 2); // Output: Sum: 3
sum(1, 2, 3, 4); // Output: Sum: 10
sum(); // Output: Sum: 0
}
}
sum()
method accepts a variable number of integers.numbers
is treated as an array, and a for-each
loop is used to iterate over the passed arguments.Although varargs are declared with ...
, Java internally converts them into an array of the specified type. For instance, in the sum()
example, the int... numbers
parameter is internally treated as int[] numbers
. This is why you can iterate over the varargs like you would with an array.
When you define a method with varargs, the varargs parameter must be the last parameter in the method signature. This is because the method might accept any number of arguments, and if the varargs parameter is not the last, it would be impossible to determine where the fixed parameters end and the varargs begin.
Example (correct):
public void print(int fixedParam, String... varArgs) {
// implementation
}
Example (incorrect):
// Compilation error
public void print(String... varArgs, int fixedParam) {
// implementation
}
A method can have only one varargs parameter. Having more than one would lead to ambiguity in determining the number of arguments for each varargs parameter.
Example (incorrect):
// Compilation error
public void example(int... numbers, String... strings) {
// implementation
}
You can pass zero arguments to a varargs method. In this case, the varargs array will simply be empty.
You can combine varargs with regular parameters, but remember that the varargs parameter must always be last in the method signature.
public static void display(String message, int... numbers) {
System.out.println("Message: " + message);
for (int number : numbers) {
System.out.println(number);
}
}
public static void main(String[] args) {
display("Numbers:", 1, 2, 3); // Valid
display("No numbers"); // Valid, no varargs passed
}
Varargs can also be used in combination with method overloading. When multiple overloaded methods are available, the most specific method signature is chosen by the compiler.
public class VarargsExample {
// Overloaded method without varargs
public static void display(int number) {
System.out.println("Single number: " + number);
}
// Method with varargs
public static void display(int... numbers) {
System.out.println("Varargs method called");
for (int number : numbers) {
System.out.println(number);
}
}
public static void main(String[] args) {
display(10); // Calls the single argument method
display(1, 2, 3, 4); // Calls the varargs method
}
}
In this example:
display(int number)
method is called when a single integer is passed.display(int... numbers)
method is called when multiple integers are passed.While varargs make the code more flexible, they do have a slight performance cost compared to regular method parameters because of the creation of an array to store the arguments. This cost is typically negligible in most cases but is something to consider in performance-critical applications.
Varargs work not only with primitive types (like int
, double
, etc.) but also with reference types such as String
or any custom object.
public class VarargsReferenceType {
public static void printNames(String... names) {
for (String name : names) {
System.out.println(name);
}
}
public static void main(String[] args) {
printNames("Alice", "Bob", "Charlie");
}
}
In this example, the printNames()
method can accept any number of String
arguments.
Since varargs are internally treated as arrays, you can pass an array directly to a varargs method:
public class VarargsExample {
public static void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}
public static void main(String[] args) {
int[] myNumbers = {1, 2, 3, 4};
printNumbers(myNumbers); // Passing an array to a varargs method
}
}
In this example, the printNumbers()
method accepts both individual arguments and arrays.
If you pass null
to a varargs method, it will be treated as if no arguments were passed, and you may encounter a NullPointerException
if you try to access the varargs array without checking for null.
public static void printNumbers(int... numbers) {
if (numbers == null) {
System.out.println("No numbers provided");
return;
}
for (int number : numbers) {
System.out.println(number);
}
}
public static void main(String[] args) {
printNumbers(null); // Output: No numbers provided
}
Varargs provide a powerful and flexible way to handle methods with variable numbers of arguments, making code cleaner and more readable. By allowing developers to pass any number of arguments (including none), varargs eliminate the need for multiple method overloads while still offering flexibility.
However, care should be taken to ensure that they are used correctly (with varargs as the last parameter) and that performance implications are considered in critical scenarios.