ProgrammingJava Developer

What are varargs (variable-length arguments) in Java, how do they work, and what pitfalls exist when using them?

Pass interviews with Hintsage AI assistant

Answer

Varargs is a syntax that allows a method to receive a variable number of arguments of a single type. They are declared using ellipsis:

public void printNames(String... names) { for (String name : names) { System.out.println(name); } }

How does it work?

The varargs parameter inside a method is simply an array of the corresponding type: String[] names in the example above. You can call the method with any number of arguments or with an array:

printNames("Igor", "Anna", "Maria"); printNames(new String[] {"Alex", "Inna"});

Nuances of usage:

  • Varargs must be the last parameter in the parameter list of the method.
  • Only one varargs parameter is allowed in a method.
  • There can be ambiguities in method calls if there is an overload between an array and varargs, as well as between different types of varargs.
  • When passing null to varargs, the method will receive null, not an empty array!

Trick question

Question: What will be the length of the varargs parameter array if you call the method without passing any arguments?

Answer: In this case, the varargs variable will refer to an array of zero length: new String[0]. It will not be null!

public void foo(Integer... args) { System.out.println(args.length); } // foo(); // Prints: 0

Examples of real errors due to ignorance of the nuances of the topic


Story

In the logging library, there was a method log(String... messages). When calling log(null), a NullPointerException occurred inside the method (expected messages to be an empty array, instead it was null). To resolve this, a null check had to be added.


Story

A developer created an overload:

public void doSomething(String[] arr) {...} public void doSomething(String... arr) {...}

When passing an array, a different method than expected was called, resulting in data loss. The difference between an array and varargs turned out to be non-obvious.


Story

In the project, a second parameter was added after varargs:

public void foo(String... args, int count) {...} // Compilation error!

This led to an error and build failure, as varargs must be the last parameter.