One Method, Any Number of Arguments
Sometimes you do not know up front how many arguments a method needs. You might want max(3, 9) one moment and max(1, 7, 4, 2, 8) the next. Without varargs you would write an overload for each count or force the caller to build an array. Varargs - short for variable arguments - let a single method accept zero, one, or many values of the same type.
You declare them by putting three dots (...) after the parameter type:
The caller passes loose values; inside the method numbers is a real array. That is the whole idea - the compiler bundles the arguments into an array for you.
Varargs Are Just an Array
There is no magic at runtime. A parameter declared int... numbers is exactly an int[] once you are inside the method. You can ask for its length, index into it, and loop over it like any other array.
Because it is genuinely an array, you can also hand a varargs method an array you already have - it accepts both forms:
The Rules: Last and Only One
Two rules keep varargs unambiguous, and the compiler enforces both:
- The varargs parameter must be last. Regular parameters come first, then the
...parameter soaks up whatever is left. - A method may have at most one varargs parameter. Two would make it impossible to tell where one ends and the next begins.
This compiles. But putting the varargs first - static void log(Object... values, String level) - is a compile error: varargs parameter must be the last. The required parameter level always precedes the ....
Where You Already Use Varargs
You have been calling varargs methods all along. System.out.printf and String.format are the classic examples - their second parameter is Object... args:
List.of(...), Arrays.asList(...), and many builder-style APIs are varargs too. That is why you can pass any number of elements to them without wrapping anything in an array yourself.
Varargs and Overloading
Varargs and overloading interact in one surprising way. When a regular overload and a varargs overload could both match a call, Java prefers the more specific one - the fixed-arity method wins:
pick(1, 2) matches both, but Java picks the non-varargs overload because it is the closer fit. The varargs method only runs when no fixed overload matches. This is usually what you want, but it means adding a varargs overload can silently change which method a call resolves to.
Watch the Empty and null Calls
Two gotchas bite people. First, calling a varargs method with no arguments hands the method an empty array, not null - so numbers.length is 0 and looping does nothing. You do not need a null check for the no-argument case:
Second, passing a literal null is ambiguous and dangerous: Java may interpret count(null) as "the entire varargs array is null" rather than "one null element", which then throws a NullPointerException when you read its length. If you truly mean a single null element, be explicit with count((Object) null).
Next: Classes
Varargs round out what you can do with method parameters - flexible argument lists on top of overloading. So far the methods have lived loosely in a class with static. Next you will see how classes really work: bundling data (fields) and behavior (methods) into your own types, which is the heart of object-oriented Java.
Frequently Asked Questions
What are varargs in Java?
Varargs (variable arguments) let a method accept any number of arguments of the same type. You declare them by putting ... after the type: int sum(int... numbers). The caller can pass zero, one, or many values, and inside the method numbers is a normal array. It is syntactic sugar - Java collects the loose arguments into an array for you.
Can a Java method have more than one varargs parameter?
No. A method can have at most one varargs parameter, and it must be the last one in the parameter list - for example void log(String level, Object... values). If it were not last, Java would not know where the variable-length part ends and the next parameter begins. Regular parameters always come before the ... parameter.
What is the difference between varargs and an array parameter in Java?
They are nearly the same at runtime - a varargs parameter int... is an int[] inside the method. The difference is at the call site: with varargs you write sum(1, 2, 3) (loose values), while with an explicit array parameter you must build and pass an array, sum(new int[]{1, 2, 3}). A varargs method also accepts an array directly, so it is the more flexible choice.