Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why varargs should be the last in method signature?

Tags:

If I try to write a method like below

public void someStuff(Object ... args, String a )

I get this error

The variable argument type Object of the method someStuff must be the last parameter.

I don't fully understand the requirement of variable argument type to be the last. Any inputs will be helpful.

like image 471
Ravi Gupta Avatar asked Jan 29 '10 12:01

Ravi Gupta


People also ask

At which position should Varargs be placed in a parameterized method?

There can be only one variable argument in a method. Variable argument (Varargs) must be the last argument.

Which is the correct declaration of Varargs method?

The varargs uses ellipsis i.e. three dots after the data type. Syntax is as follows: return_type method_name(data_type... variableName){}

Why do we use Varargs?

Varargs can be used when we are unsure about the number of arguments to be passed in a method. It creates an array of parameters of unspecified length in the background and such a parameter can be treated as an array in runtime.

What does Varargs mean?

Varargs is a short name for variable arguments. In Java, an argument of a method can accept arbitrary number of values.


3 Answers

The variable argument has to be the last so the compiler can work out which argument is which.

For example, say you pass

"test", "test", "test", "test"

into your function

public void someStuff(Object ... args, String a)

Java cannot work out if you want the args variable to contain 3 or 4 strings. It may be obvious to you at the time of writing but it's ambiguous.

However, when it's the other way around

public void someStuff(String a, Object ... args)

The Java compiler sees the first string, stick it into "a" and then knows that the remaining strings can be safely put into args and there is no ambiguity over the variables.

like image 58
linead Avatar answered Sep 24 '22 01:09

linead


It follows the C convention. The C convention in turn is based on CPU architectures which pass arguments on the stack. The first non-vararg arguments end up at a fixed offset in the stackframe. If you could put the vararg arguments first, the stack offset of the following arguments would depend on how many vararg parameters you would have passed. This would greatly complicate the amount of code needed to access them.

In your example, with String a first, it's conceptually at offset 0 independent how the number of vararg arguments that follow. But with String a last, it could be at offset 0, 4, 8, 12 etc - you'd have to calculate args.size * 4 everytime you needed String a.

like image 23
MSalters Avatar answered Sep 27 '22 01:09

MSalters


Because that would make the language unnecessarily complex. Imagine if you also allowed other syntaxes:

public void someStuff(String a, Object ... args, String b)
{
}

Or even:

public void someStuff(String a, Object ... args, int b, Object ... args2)
{
}

This second syntax means a string followed by any number of arguments of type Object, followed by an integer, followed by more objects. Sure you could design a language that could accept things like that, but what if you also wanted to specify that the args2 must contain at least one element, but args can be empty? Why can't we do that too? You could design such a language.

It boils down to, how complicated do you want the rules to be? In this case they chose a simple option that fulfils the needs.

like image 9
Mark Byers Avatar answered Sep 23 '22 01:09

Mark Byers