简体   繁体   中英

Object arrays in method signatures

Consider the following method signatures:

public fooMethod (Foo[] foos) { /*...*/ }

and

public fooMethod (Foo... foos) { /*...*/ }

Explanation: The former takes an array of Foo-objects as an argument - fooMethod(new Foo[]{..}) - while the latter takes an arbitrary amount of arguments of type Foo, and presents them as an array of Foo:s within the method - fooMethod(fooObject1, fooObject2, etc... ).

Java throws a fit if both are defined, claiming that they are duplicate methods. I did some detective work, and found out that the first declaration really requires an explicit array of Foo objects, and that's the only way to call that method. The second way actually accepts both an arbitrary amount of Foo arguments AND also accepts an array of Foo objects.

So, the question is, since the latter method seems more flexible, are there any reasons to use the first example, or have I missed anything vital?

These methods are actually the same.

This feature is called varargs and it is a compiler feature. Behind the scenes is is translates to the former version.

There is a pitfall if you define a method that accepts Object... and you sent one parameter of type Object[]!

I'd like to add to Shimi's explanation to add that another restriction of the varargs syntax is that the vararg must be the last declared parameter. So you can't do this:

void myMethod(String... values, int num);

This means that any given method can only have a single vararg parameter. In cases where you want to pass multiple arrays, you can use varargs for only one of them.

In practice, varargs are at their best when you are treating the args as an arbitrary number of distinct values, rather than as an array. Java5 maps them to an array simply because that was the most convenient thing to do.

A good example is String.format(). Here, the varargs are matched against the format placeholders in the first argument.

The latter was introduced in Java 5 and existing libraries are gradually being reworked to support it. You might still use the former to stress that the method requires 2+ inputs, plus there are restrictions on where the ... can be used.

There are certainly no performance issues or things like that to consider, so it comes down to semantics.

Do you expect the caller of your method to have an array of Foo's ready at hand? Then use the Foo[] version. Use the varargs variant to emphasize the possibility of having a "bunch" of Foo's instead of an array.

A classical example for varargs ist the string-format (in C#, dunno how its called in Java):

string Format(string formatString, object... args)

Here you expect the args to be of different types, so having an array of arguments would be quite unusal, hence the varargs variant.

On the other hand in something like

string Join(string[] substrings, char concatenationCharacter)

using an Array is perfectly reasonable.

Also note that you can have multiple array-parameters and only one vararg parameter at the end of the paramater-list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM