public static int add(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
} return total;
}Java Varargs: Variable-Length Argument Lists in Method Declarations
Direct Answer & Core Concept
Java Varargs, short for variable-length arguments, allow a method to accept zero, one, or many arguments of the same type without requiring the caller to create an array manually. Varargs are useful when you do not know in advance how many values a method will receive.
The feature uses the ... syntax in a method parameter declaration. Inside the method, the varargs parameter behaves like an array, which makes it easy to loop through and process the supplied values.
For example, instead of creating separate methods for one number, two numbers, or five numbers, you can create one method that accepts any number of integers.
The same method can now be called with different numbers of arguments:
System.out.println(add());
System.out.println(add(10));
System.out.println(add(10, 20));
System.out.println(add(10, 20, 30, 40));Detailed Explanation & Mechanics
What Is Varargs in Java?
A varargs parameter allows a method to receive a variable number of arguments. It is declared by placing three dots (...) after the parameter type.
returnType methodName(dataType... parameterName) {
// method body
}For example:
public static void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}The method can accept any number of int values, including no values.
printNumbers();
printNumbers(10);
printNumbers(10, 20, 30);Java internally treats the varargs parameter as an array.
Why Use Varargs?
Without varargs, you may need to create multiple overloaded methods when the number of arguments can change.
For example:
public static int add(int a, int b) {
return a + b;
}public static int add(int a, int b, int c) {
return a + b + c;
}public static int add(int a, int b, int c, int d) {
return a + b + c + d;
}This becomes inconvenient if callers may provide many values.
With varargs, one method can handle all these cases:
public static int add(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
} return total;
}Now the same method works with different argument counts.
Varargs Syntax in Java
The basic syntax is:
dataType... parameterNameFor example:
public static void display(String... names) {
for (String name : names) {
System.out.println(name);
}
}The ... is called the varargs notation.
A method can have only one variable-arity parameter, and that parameter must be the last parameter in the method declaration.
Simple Java Varargs Example
Here is a basic example that calculates the sum of numbers.
public class VarargsExample {
static int sum(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
} return total;
} public static void main(String[] args) {
System.out.println(sum(10, 20));
System.out.println(sum(10, 20, 30));
System.out.println(sum(5, 10, 15, 20, 25));
}
}Output:
306075The caller does not need to create an array explicitly.
Varargs Can Accept Zero Arguments
One useful property of varargs is that the caller can provide no arguments.
public static void show(int... numbers) {
System.out.println("Number of arguments: " + numbers.length);
}Calling:
show();produces:
Number of arguments: 0In this case, Java supplies an empty array to the method.
This makes varargs useful for methods where providing values is optional.
Varargs Can Accept One Argument
A varargs method can also receive exactly one value.
public static void show(int... numbers) {
System.out.println(numbers[0]);
}Calling:
show(100);prints:
100The method receives the value through an array containing one element.
Varargs Can Accept Multiple Arguments
You can provide as many compatible arguments as needed.
public static void show(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}Example:
show(10, 20, 30, 40, 50);The values are available inside the method as an array.
Conceptually, the call behaves similarly to passing an array:
show(new int[] {
10, 20, 30, 40, 50
});Varargs Are Internally Arrays
A varargs parameter is represented as an array inside the method.
Consider:
public static void display(String... values) {
System.out.println(values.getClass());
}The parameter values behaves like a String[].
You can use:
values.lengthand array indexing:
values[0]You can also use enhanced for loops:
for (String value : values) {
System.out.println(value);
}Therefore, learning arrays makes varargs easy to understand.
Passing an Array to a Varargs Method
You can pass an existing array directly to a compatible varargs parameter.
public static void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}Now create an array:
int[] values = {
10, 20, 30, 40
};
printNumbers(values);This works because int... is handled as int[] inside the method.
You can therefore call the same method using individual arguments or an array.
printNumbers(10, 20, 30);
int[] values = {
40, 50, 60
};
printNumbers(values);Varargs With Other Parameters
A method can have normal parameters before the varargs parameter.
For example:
public static void printMessage(String message, int... numbers) {
System.out.println(message);
for (int number : numbers) {
System.out.println(number);
}
}Calling:
printMessage("Numbers:", 10, 20, 30);produces:
Numbers:102030The fixed parameter comes first, followed by the variable-length parameter.
Varargs Must Be the Last Parameter
The varargs parameter must appear at the end of the parameter list.
Correct:
public static void test(String name, int... numbers) {
}Incorrect:
public static void test(int... numbers, String name) {
}The second declaration is invalid because Java needs to know where the variable-length arguments end.
For example, this would be ambiguous:
test(10, 20, 30, "John");Java would not have a clear way to determine which values belong to the varargs parameter.
Only One Varargs Parameter Is Allowed
A method cannot have two variable-length parameters.
This is invalid:
public static void test(int... numbers, String... names) {
}Java allows only one varargs parameter in a method declaration.
A typical valid declaration is:
public static void test(String name, int... numbers) {
}Here, name is fixed and numbers is variable-length.
Varargs With Different Data Types
Varargs work with reference types as well as primitive types.
Integer Varargs
public static void numbers(int... values) {
for (int value : values) {
System.out.println(value);
}
}String Varargs
public static void names(String... names) {
for (String name : names) {
System.out.println(name);
}
}Call:
names("Alice", "Bob", "Charlie");Double Varargs
public static void prices(double... prices) {
for (double price : prices) {
System.out.println(price);
}
}The component type of the varargs determines what values can be supplied.
Varargs and Primitive Types
Varargs can directly use primitive types.
For example:
public static int calculate(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
} return total;
}This method receives an int[] internally.
Other primitive types can also be used:
double...long...float...boolean...char...byte...short...For example:
public static void display(double... values) {
for (double value : values) {
System.out.println(value);
}
}Varargs and Object Types
You can also use a reference type as the varargs component type.
public static void printObjects(Object... objects) {
for (Object object : objects) {
System.out.println(object);
}
}Now different reference and boxed values can be supplied:
printObjects("Java", 100, 25.5, true);Autoboxing allows primitive values such as 100 and 25.5 to be represented as wrapper objects when passed to an Object... parameter.
Varargs and Method Overloading
Varargs participate in Java's method-overloading rules.
Consider:
public static void show(int value) {
System.out.println("Single int");
}public static void show(int... values) {
System.out.println("Varargs");
}Now:
show(10);The fixed-arity method is selected because it is a more specific direct match than the variable-arity alternative.
But:
show(10, 20);can use the varargs method.
When overloading methods with varargs, be careful because combinations of overloaded methods can create ambiguity.
Varargs and Ambiguous Method Calls
Poorly designed overloads can produce ambiguous calls.
For example:
public static void test(int... values) {
}public static void test(boolean... values) {
}Now this call:
test();does not provide enough information for Java to determine which method should be selected.
Both methods can accept zero arguments.
The compiler therefore reports an ambiguity error.
This is one reason to avoid unnecessary varargs overloads with unrelated parameter types.
Varargs With Null
Because a varargs parameter is an array internally, null can be relevant.
For example:
public static void print(String... values) {
System.out.println(values == null);
}This is valid:
print((String[]) null);The method receives a null array rather than an empty array.
That is different from:
print();where the method receives an empty array.
Therefore, code should not automatically assume a varargs array is non-null if callers can explicitly pass a null array.
Calling a Varargs Method With No Values vs Null
These two calls are conceptually different:
print();and:
print((String[]) null);The first represents an empty argument list.
The second explicitly passes a null array.
For example:
public static void print(String... values) {
if (values == null) {
System.out.println("Null array");
return;
} System.out.println("Arguments: " + values.length);
}Output for:
print();is:
Arguments: 0While:
print((String[]) null);prints:
Null arrayVarargs and Generic Types
Varargs can be used with generic reference types.
For example:
public static <T> void print(T... values) {
for (T value : values) {
System.out.println(value);
}
}You can call:
print("Java", "Python", "Go");or:
print(10, 20, 30);However, generic varargs can sometimes produce compiler warnings because of the interaction between arrays, generics, and type erasure.
Heap Pollution and Generic Varargs
Generic varargs require additional care because Java arrays retain runtime component-type information while generic type arguments are erased.
For example:
static <T> void display(T... values) {
for (T value : values) {
System.out.println(value);
}
}Depending on how such a method is implemented or called, the compiler may issue an unchecked or unsafe operation warning.
The issue is related to heap pollution, where a variable of a parameterized type may refer to an object that is not actually of the expected parameterized type.
Do not suppress such warnings blindly. First verify that the method is type-safe.
@SafeVarargs
Java provides the @SafeVarargs annotation for certain methods whose implementation is known to be safe despite using generic varargs.
For example:
@SafeVarargspublic static <T> void print(T... values) {
for (T value : values) {
System.out.println(value);
}
}@SafeVarargs tells the compiler and readers that the method has been reviewed for unsafe generic-varargs operations.
It should not be used simply to hide warnings. The method should actually be safe.
The annotation is applicable to appropriate static, final, and private instance methods, where overriding cannot introduce an unsafe implementation.
Varargs vs Array Parameter
These declarations look similar but provide different calling syntax.
Array Parameter
public static void print(int[] values) {
}Call:
int[] values = {
10, 20, 30
};
print(values);You cannot directly call:
print(10, 20, 30);Varargs Parameter
public static void print(int... values) {
}Now both forms are possible:
print(10, 20, 30);and:
int[] values = {
10, 20, 30
};
print(values);So varargs provide more convenient calling syntax while the method still receives an array.
Varargs vs Method Overloading
Suppose you want to support different numbers of values.
Without varargs:
sum(int a)sum(int a, int b)sum(int a, int b, int c)sum(int a, int b, int c, int d)With varargs:
sum(int... values)The second approach is usually much easier to maintain when the operation naturally accepts an arbitrary number of values.
However, varargs should not replace meaningful overloads when different argument counts have different semantics.
Example: Finding the Maximum Number
Varargs are useful for utility methods such as finding the largest number.
public class MaximumExample {
static int maximum(int... numbers) {
if (numbers.length == 0) {
throw new IllegalArgumentException("At least one number is required");
} int max = numbers[0];
for (int number : numbers) {
if (number > max) {
max = number;
}
} return max;
} public static void main(String[] args) {
System.out.println(maximum(10, 50, 20));
System.out.println(maximum(5, 100, 25, 75));
}
}Output:
50100Notice that the method explicitly checks for an empty argument list because the algorithm requires at least one value.
Example: Calculating an Average
Here is another practical example:
public static double average(double... values) {
if (values.length == 0) {
throw new IllegalArgumentException("At least one value is required");
} double total = 0;
for (double value : values) {
total += value;
} return total / values.length;
}Call:
System.out.println(average(10, 20, 30));Output:
20.0Varargs make this method convenient because the caller does not need to manually construct a double[].
Example: Building a Message
Varargs are not limited to mathematical operations.
public static String joinWords(String... words) {
return String.join(" ", words);
}Call:
String message = joinWords( "Java", "is", "easy", "to", "learn");
System.out.println(message);Output:
Java is easy to learnThis demonstrates how varargs can simplify utility methods that accept a flexible number of values.
Performance Considerations
Varargs are convenient, but they are not completely free.
When individual arguments are supplied, Java needs to package them into an array for the method invocation.
For example:
sum(10, 20, 30);conceptually involves an array containing those values.
For normal application code, this overhead is usually insignificant. However, in extremely performance-sensitive code that executes millions of times, unnecessary temporary arrays and boxing can matter.
In such cases, measure the actual workload before changing a clean varargs API.
Varargs With Boxing
Primitive varargs and reference varargs have different performance characteristics.
For example:
static void process(int... values) {
}uses an int[].
But:
static void process(Integer... values) {
}uses an Integer[].
Passing primitive integers to the second method can involve boxing:
process(10, 20, 30);The values may need to become Integer objects.
Therefore, use primitive varargs when you specifically need primitive values and want to avoid unnecessary boxing.
Common Mistakes With Java Varargs
Mistake 1: Putting Varargs Before Another Parameter
Incorrect:
void test(int... numbers, String name) {
}The varargs parameter must be last.
Mistake 2: Declaring Multiple Varargs Parameters
Incorrect:
void test(int... numbers, String... names) {
}A method can have only one variable-arity parameter.
Mistake 3: Assuming Varargs Are Not Arrays
Inside the method:
void test(int... values) {
}values behaves as an int[].
You can use:
values.lengthvalues[0]and enhanced for loops.
Mistake 4: Forgetting the Empty Case
A varargs method can receive zero arguments:
sum();If the algorithm requires at least one value, validate the length:
if (values.length == 0) {
throw new IllegalArgumentException("At least one value is required");
}Mistake 5: Using Generic Varargs Without Understanding the Warning
Generic varargs can produce unchecked warnings because of type erasure and arrays.
Do not automatically add:
@SuppressWarnings("unchecked")or:
@SafeVarargswithout understanding why the warning occurs and whether the implementation is actually safe.
Java Varargs Best Practices
Use varargs when the method naturally accepts a variable number of arguments and all arguments have the same logical type.
Keep the varargs parameter at the end and avoid creating confusing overload combinations that can make calls ambiguous.
Validate the empty case when your algorithm requires at least one value, and be careful with null arrays and generic varargs.
For performance-sensitive code, remember that varargs can involve array creation and that wrapper-type varargs can involve boxing.
Varargs Example for a Utility Class
Here is a complete example combining several concepts:
public class MathUtils {
public static int sum(int... numbers) {
int total = 0;
for (int number : numbers) {
total += number;
} return total;
} public static int maximum(int... numbers) {
if (numbers.length == 0) {
throw new IllegalArgumentException( "At least one number is required");
} int max = numbers[0];
for (int number : numbers) {
if (number > max) {
max = number;
}
} return max;
} public static void main(String[] args) {
System.out.println("Sum: " + sum(10, 20, 30));
System.out.println("Maximum: " + maximum(15, 70, 25, 40));
}
}Output:
Sum: 60Maximum: 70This is a typical use case for varargs in reusable utility methods.
Key Rules of Java Varargs
| Rule | Explanation |
|---|---|
| Syntax | type... name |
| Internal representation | Array |
| Number of arguments | Zero or more |
| Position | Must be the last parameter |
| Number of varargs parameters | Only one |
| Arrays accepted | Yes, compatible array can be passed |
| Primitive types | Supported |
| Reference types | Supported |
| Generic types | Supported with additional safety considerations |
| Empty invocation | Allowed |
| Main benefit | Convenient variable-length method calls |
Frequently Asked Questions
What is varargs in Java?
Varargs allow a Java method to accept a variable number of arguments. They are declared using three dots, such as int... numbers.
What does ... mean in Java?
In a method parameter declaration, ... indicates a variable-arity parameter, also called varargs.
Is a varargs parameter an array?
Yes. Inside the method, a varargs parameter is represented and accessed as an array.
Can a varargs method accept zero arguments?
Yes.
void test(int... values) {
}The method can be called as:
test();Can I pass an array to a varargs method?
Yes.
int[] values = {
10, 20, 30
};
test(values);Can a method have two varargs parameters?
No. Java allows only one variable-arity parameter, and it must be the final parameter.
Can varargs be followed by another parameter?
No.
Correct:
void test(String name, int... numbers)Incorrect:
void test(int... numbers, String name)Are varargs faster than arrays?
Varargs are primarily a convenience feature. When individual arguments are supplied, Java packages them into an array, so there can be allocation overhead. For most normal code, this is not a concern.
What is the difference between int... and int[]?
Inside the method, both represent an int array. The important difference is calling syntax: int... allows individual arguments such as method(1, 2, 3) as well as an int[].
What is @SafeVarargs?
@SafeVarargs can be used on eligible methods to indicate that their generic varargs implementation has been checked and does not perform unsafe operations with the varargs array.
Suggested Graphics and Page Design
Graphic 1 — Varargs Concept
Create a simple diagram:
Java Varargs
|
int... numbers
|
┌─────────────┼─────────────┐
↓
↓
↓
10, 20 10, 20, 30 No values
| | |
└─────────────┼─────────────┘
↓
int[]Caption:
Java varargs allow a method to receive zero or more arguments as an array.
Graphic 2 — Parameter Position
Show:
Correct:method(String name, int... numbers) ↑ LASTIncorrect:method(int... numbers, String name) ↑ ↑ VARARGS AFTER VARARGSGraphic 3 — Varargs vs Array
Use a side-by-side comparison:
Arraymethod(int[] values)↓method(new int[] {
10, 20, 30
})Varargsmethod(int... values)↓method(10, 20, 30)Runnable Code Example: Java Varargs
Java 17+public class VarargsDemo {
public static int sumNumbers(String label, int... values) {
int total = 0;
for (int v : values) {
total += v;
} System.out.println(label + ": " + total);
return total;
} public static void main(String[] args) {
sumNumbers("Zero items");
sumNumbers("Two items", 10, 20);
sumNumbers("Four items", 1, 2, 3, 4);
}
}