When to prefer a varargs list to an array?
Asked Answered
W

5

12

I'm implementing an API an have a method which you pass a list of paths where the program reads resources from

public void importFrom(String... paths) {

}

I'm using varargs to make calling the method as convenient as possible to the user, like so

obj.importFrom("/foo", "/foo/bar);

Is this an appropriate use of varargs? Or is passing in an array better?

Wordplay answered 31/10, 2011 at 8:31 Comment(1)
You can still pass an array to a varargs method, it will behave the same.Fredel
O
10

In your case varargs is just fine. You don't really need to make an array of the paths that you will be importing because there's nothing you want to do with these paths other than to pass them along to your importFrom method.

The varargs functionality saves you from having to explicitly create an array solely for the purpose of passing a collection of values to a one-off method, which you do appear to have here.

BTW, you can still pass in an array if you want to

public class VarargsDemo {
    public static void f(String... args) {
        for (String s: args) {
            System.out.println(s);
        }
    }
    public static void main(String[] args) {
        String[] english = new String[]{"one", "two", "three"};
        f(english);
        f("uno", "dos", "tres");
    }
}

Because the behavior is the same, the difference comes down to a (probably minor) question of what you want the method signature to "say". When you declare a method to take an explicit array parameter, it's almost as if you want to stress that you want to operate on an array object, something that has been defined outside the method and has its own existence and importance outside the method, and one in which, perhaps, operations like indexing matter. When declaring the method with varargs, its as if you are saying "just give me a bunch of items".

Then again, this doesn't have to be true; the JVM doesn't know the difference, all it sees is an array at run time. Many programmers won't bother splitting hairs over the intent of the method signature. Varargs is all about making the calls convenient.

That said, the main limitation of varargs is that such a parameter must be the last one of the method. In your case this is not a problem, but in general it is something to consider.

Orlina answered 31/10, 2011 at 8:38 Comment(2)
+1 for the array passing -- I still find the paragraph about "distince array object" a little confusing: The only reason I see for passing an actual array is so the caller can see changes made by the callee (reversing, sorting) -- but searching wouldn't require this?Fredel
Yes, that was poorly written and perhaps not terribly important. I reworded it a bit to try to make it less confusing and also show that it is kind of minor issue, if it is indeed an issue at all. Thanks.Orlina
P
3

Since varargs arguments get compiled into a single array argument you could generally prefer varargs since this might be more convinient in some cases and still allows to pass an array in other cases.

public void importFrom(String... paths)
{
}

compiles into

public void importFrom(String[] paths)
{
}

Alternatively you could also use Iterable<String> to make it easier to pass the arguments as collection.

Perjured answered 31/10, 2011 at 8:42 Comment(0)
C
2

The answer depends on the intended use of your function. If the user typically knows at coding time which arguments he wants to pass in, varargs is the way to go. If the user needs to be able to determine the number of arguments at runtime, an array argument will make life a lot easier for him (or her).

Crissie answered 31/10, 2011 at 8:35 Comment(2)
I think he's talking about an open array parameters. In older languages the only way to determine the end of the arguments was to use a canary, or format string. Not so in java. For simplicity, I would use varargs as you don't need to make a temporary list making the code potentially more comprehensibleToreador
"If the user needs to be able to determine the number of arguments at runtime" he would just pass an array.Fredel
M
1

I think the other alternative is to use List<String>. Personally I would use a List if there are more than a few arguments or if arguments are automatically processed from somewhere (parsed from a file for example).

If you will be writing the arguments manually in the code, then I would prefer using the varargs as you proposed.

Mushy answered 31/10, 2011 at 8:36 Comment(0)
S
0

It's okay for your method to accept either list or varargs.

Here's a little history of why varargs exist, say you have multiple data and a method which takes a list:

String a = "hello";
int b = 50;

public void printData(List<Object> objects) {
  for (Object object : objects) {
    System.out.println(object.toString());
  }
}

Then to pass the data to the printData() method, you'd need to create an array from the data, then pass it to the method. But with varargs, you don't need to do that anymore.

From the documentation (https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html):

It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process.

Strophanthus answered 4/1 at 4:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.