Varargs in Java
A variable arity parameter lets a method accept any number of arguments, and inside the method it is simply an array.
-
Java Basics
- Introduction to Java
- Setting Up Java and Writing Your First Program
- Variables, Data Types and Literals in Java
- Type Casting and Type Conversion in Java
- Operators and Expressions in Java
- Input and Output in Java
- Comments, Keywords and Naming Conventions in Java
- Control Flow in Java: if, else and switch
- Loops in Java: for, while and do-while
- Methods
- Arrays and Strings
-
OOP
- Classes and Objects in Java
- Constructors in Java
- The this Keyword in Java
- The static Keyword in Java
- Encapsulation in Java
- Access Modifiers in Java
- Inheritance in Java
- Method Overriding and super in Java
- Polymorphism in Java
- Abstraction, Abstract Classes and Interfaces in Java
- Composition, Aggregation and Association in Java
- The Object Lifecycle in Java
- Core Java
- Exception Handling
-
Collections
- The Java Collections Framework
- List in Java: ArrayList, LinkedList, Vector and Stack
- Set in Java: HashSet, LinkedHashSet and TreeSet
- Map in Java: HashMap, LinkedHashMap and TreeMap
- How HashMap Works Internally in Java
- Queue and Deque in Java: ArrayDeque and PriorityQueue
- Iterators in Java
- Comparable and Comparator in Java
- Collections Utilities and Choosing the Right Collection
- Generics
- Java 8+
- Stream API
- Date and Time
- File and I/O
-
Multithreading
- Threads in Java: Processes, Runnable and Thread
- Thread Lifecycle in Java
- Synchronization in Java: synchronized and volatile
- Locks and Atomic Classes in Java
- Race Conditions and Deadlocks in Java
- The Executor Framework and Thread Pools in Java
- Future and CompletableFuture in Java
- Concurrent Collections in Java
- The Java Memory Model
- JVM and Memory
- Advanced Java
- Networking
- JDBC
- Testing
Definition
A varargs parameter, written with three dots after the type, accepts zero or more arguments of that type. The compiler packs them into an array before the call.
Why it exists
Before varargs, a method that accepted an unknown number of values needed either an explicit array at every call site or a family of overloads. Varargs removes that noise for the caller.
Syntax and example
public static int sum(int... values) {
int total = 0;
for (int value : values) { // values is an int[]
total += value;
}
return total;
}System.out.println(sum()); // 0, an empty array
System.out.println(sum(5)); // 5
System.out.println(sum(5, 10, 15)); // 30
System.out.println(sum(new int[]{1, 2})); // 3, an array may be passed directlyRules
- A method may have at most one varargs parameter.
- It must be the last parameter in the list.
- Inside the method it is an ordinary array, so
lengthand indexing work. - It is never
nullwhen called normally; with no arguments it is an empty array.
public static String join(String separator, String... parts) { // correct
return String.join(separator, parts);
}
// public static String join(String... parts, String separator) // will not compileWhere it is used in the standard library
System.out.printf("%s is %d%n", "age", 30); // Object... args
List<String> cities = List.of("Pune", "Kochi", "Surat"); // E... elements
int biggest = Collections.max(List.of(3, 9, 4));Overloading and varargs
static void report(String message) { System.out.println("exact"); }
static void report(String... messages) { System.out.println("varargs"); }
report("hello"); // prints "exact" - varargs is the last resortThe compiler considers a varargs method only after exact matches, widening and boxing have all failed. That makes behaviour stable when an overload is added later, but it can also surprise you.
The generic varargs warning
@SafeVarargs
public static <T> List<T> listOf(T... items) {
return new ArrayList<>(Arrays.asList(items));
}An array of a generic type cannot be created safely, so the compiler warns about a possible heap pollution. When the method only reads the array and never stores anything into it or exposes it, the warning can be suppressed with @SafeVarargs. The annotation is allowed only on methods that cannot be overridden, which means static, final or a constructor.
Common mistakes
- Passing
nullas the only argument.sum(null)passes a null array rather than an empty one, and the loop then throws. - Assuming a primitive array widens.
sum(new Integer[]{1, 2})does not matchint.... - Using varargs for a fixed number of arguments, which throws away compile time checking.
- Placing the varargs parameter anywhere but last.
Best practices
- Use varargs only where the count genuinely varies.
- If at least one argument is required, declare it separately:
process(String first, String... rest). That makes the requirement a compile error rather than a runtime check. - Do not overload a varargs method with a similar fixed arity one unless the choice is obvious.
- Remember the hidden array allocation on every call in a hot loop.
Practice
- Write a method that returns the largest of any number of
intvalues and throws when called with none. - Why does
sum()return 0 rather than throwing? - Predict what
report("a", "b")prints in the overload example above. - Change
joinso the separator comes last, and explain the compiler error.
Conclusion
Varargs is convenience for the caller and an array for the implementer. Keep it last, keep it genuinely variable, and require the first argument separately when the method needs at least one.