Varargs in Java – Methods with Variable Arguments
Varargs (variable-length arguments), introduced in Java 5, let a method accept zero or more arguments of the same type. You declare the last parameter with three dots, as in int... numbers, and callers can pass any number of values without building an array themselves. Inside the method, the parameter is an ordinary array.
This tutorial covers the syntax, rules, JDK examples, how varargs interact with overloading, common pitfalls, and @SafeVarargs for generic varargs.
1. Syntax and a First Example
returnType methodName(Type... name) { ... } // name is a Type[] inside
returnType methodName(A a, B b, Type... name) { ... } // varargs must come last
public class VarargsBasics {
// 'int... numbers' accepts zero or more ints; inside the method it is an int[]
static int sum(int... numbers) {
int total = 0;
for (int n : numbers) total += n;
return total;
}
public static void main(String[] args) {
System.out.println("sum() = " + sum());
System.out.println("sum(5) = " + sum(5));
System.out.println("sum(1, 2, 3, 4) = " + sum(1, 2, 3, 4));
System.out.println("sum(new int[]{..}) = " + sum(new int[] {10, 20})); // an array works too
}
}
sum() = 0
sum(5) = 5
sum(1, 2, 3, 4) = 10
sum(new int[]{..}) = 30
The compiler converts sum(1, 2, 3, 4) into sum(new int[] {1, 2, 3, 4}). That is why an explicit array is also accepted, and why calling with no arguments gives an empty (not null) array.
2. Varargs with Other Parameters
public class VarargsWithOtherParams {
// Regular parameters first; the varargs parameter must be last (and only one is allowed)
static String tag(String label, String... values) {
return label + values.length + " -> " + String.join(" | ", values);
}
static void log(String level, String format, Object... args) {
System.out.println("[" + level + "] " + String.format(format, args));
}
public static void main(String[] args) {
System.out.println(tag("languages: ", "Java", "Kotlin", "Scala"));
System.out.println(tag("empty: "));
log("INFO", "User %s logged in from %s", "asha", "Pune");
log("WARN", "Disk usage at %d%%", 91);
}
}
languages: 3 -> Java | Kotlin | Scala empty: 0 -> [INFO] User asha logged in from Pune [WARN] Disk usage at 91%
3. Rules
- A method can have only one varargs parameter.
- It must be the last parameter.
- Inside the method it is an array: use
.length, indexes and loops. - Callers may pass zero or more values, or an array of the right type.
maincan be declared aspublic static void main(String... args).
4. Varargs in the JDK
import java.nio.file.Path;
import java.util.*;
public class JdkVarargs {
public static void main(String[] args) {
List<String> list = List.of("a", "b", "c"); // List.of(E... elements)
List<Integer> nums = Arrays.asList(3, 1, 2); // Arrays.asList(T... a)
System.out.println(list + " " + nums);
System.out.println(String.format("%s has %d items", "cart", 3)); // format(String, Object...)
System.out.println(String.join("-", "2026", "10", "11")); // join(CharSequence, CharSequence...)
System.out.println(Path.of("home", "asha", "notes.txt")); // Path.of(String, String...)
System.out.printf("printf is varargs too: %.2f%n", Math.PI);
}
}
[a, b, c] [3, 1, 2] cart has 3 items 2026-10-11 home/asha/notes.txt printf is varargs too: 3.14
Other examples include EnumSet.of, Stream.of, Collections.addAll and Objects.hash.
5. Overloading and Pitfalls
import java.util.Arrays;
import java.util.List;
public class VarargsPitfalls {
static void show(Object... items) { System.out.println(items.length + " argument(s): " + Arrays.deepToString(items)); }
static void pick(int a, int b) { System.out.println("pick(int, int)"); }
static void pick(int... values) { System.out.println("pick(int...)"); }
@SafeVarargs // promises the method does not misuse the generic array
static <T> List<T> listOf(T... items) { return List.of(items); }
public static void main(String[] args) {
show("x", "y"); // 2 arguments
show((Object) null); // 1 argument: a null element
show((Object[]) new String[] {"p", "q"}); // an array is passed AS the varargs array: 2 arguments
show((Object) new String[] {"p", "q"}); // cast: passed as ONE argument
pick(1, 2); // fixed-arity overload wins
pick(1, 2, 3); // only varargs fits
System.out.println(listOf("red", "green"));
}
}
2 argument(s): [x, y] 1 argument(s): [null] 2 argument(s): [p, q] 1 argument(s): [[p, q]] pick(int, int) pick(int...) [red, green]
- Overloading: varargs methods are chosen last. A fixed-arity overload that fits always wins (see Method Overloading).
- Arrays: passing an array to
Object...spreads it into separate arguments; cast toObjectto pass the array as a single argument. - null:
show(null)passes a null array (and the compiler warns);show((Object) null)passes one null element. - Ambiguity: overloads like
m(int...)andm(Integer...)makem()ambiguous. - Performance: each call allocates an array. For hot paths, APIs such as
List.ofprovide fixed-arity overloads for small counts.
6. Generic Varargs and @SafeVarargs
A generic varargs parameter (T... items) creates an array of a non-reifiable type, which can lead to heap pollution, so the compiler warns. If the method only reads the elements and never stores or exposes the array unsafely, annotate it with @SafeVarargs to suppress warnings at every call site. It is allowed on static methods, final instance methods, private methods and constructors.
7. Summary
- Varargs (
Type... name) accept zero or more arguments and are arrays inside the method. - Only one varargs parameter is allowed, and it must be last.
- Fixed-arity overloads are preferred over varargs during overload resolution.
- Watch out for arrays and
nullpassed toObject.... - Use
@SafeVarargsfor safe generic varargs methods.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is varargs in Java?
A feature that lets a method accept a variable number of arguments of the same type, declared with three dots, such as int... values.
Q2. How are varargs implemented internally?
The compiler packs the arguments into an array and passes it; inside the method the parameter is an ordinary array.
Q3. Can a method have two varargs parameters?
No. Only one varargs parameter is allowed.
Q4. Why must varargs be the last parameter?
Otherwise the compiler could not tell where the variable arguments end and the next parameter begins.
Q5. What happens when no arguments are passed?
The method receives an empty array (length 0), not null.
Q6. Can I pass an array to a varargs method?
Yes. An array of the matching type is passed directly as the varargs array.
Q7. Can main use varargs?
Yes. public static void main(String... args) is equivalent to String[] args.
Q8. How do varargs affect overloading?
Varargs methods are considered only after no fixed-arity method matches, even with widening or boxing.
Q9. What is @SafeVarargs?
An annotation asserting that a generic varargs method does not perform unsafe operations on its array, suppressing heap-pollution warnings.
Q10. What is heap pollution?
A situation where a variable of a parameterized type refers to an object of a different type, which can cause unexpected ClassCastExceptions.
Q11. Can a varargs parameter be null?
Yes, if the caller explicitly passes a null array. Defensive methods may check for it.
Q12. Is String.format a varargs method?
Yes: format(String format, Object... args). So are printf, String.join and List.of.
Q13. Can constructors use varargs?
Yes, constructors can declare a varargs parameter just like methods.
Q14. Do varargs affect performance?
Each call creates an array, which is usually negligible. Performance-critical APIs sometimes add fixed-arity overloads to avoid the allocation.
Q15. Can varargs be used with primitives?
Yes. int... creates an int[] without boxing.
Q16. What is the difference between Type... and Type[] parameters?
Inside the method both are arrays. With Type..., callers may also pass individual values or nothing; with Type[], they must pass an array.
Q17. Can I override a varargs method with an array parameter?
It compiles with a warning, because the signatures are equivalent, but callers through the subclass type then lose the varargs syntax. Keep the same form.
Q18. How can I require at least one argument?
Declare a regular parameter before the varargs: max(int first, int... rest).
Q19. Which Java version introduced varargs?
Java 5, together with generics, autoboxing and the enhanced for loop.
Q20. Why does passing a String[] to Object... give a warning?
It is unclear whether you mean the array as one argument or its elements as many. Cast to Object or Object[] to state your intent.