Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java varargs method param list vs. array

Varargs:

public static void foo(String... string_array) { ... } 

versus

Single array param:

public static void bar(String[] string_array) { ... } 

Java 1.6 seems to accept/reject the following:

String[] arr = {"abc", "def", "ghi"}; foo(arr);  // accept bar(arr);  // accept foo("abc", "def", "ghi");  // accept bar("abc", "def", "ghi");  // reject 

Assuming the above is true/correct, why not always use varargs instead of single array param? Seems to add a touch of caller flexiblity for free.

Can an expert share the internal JVM difference, if there is one?

Thanks.

like image 241
kevinarpe Avatar asked Mar 23 '11 13:03

kevinarpe


People also ask

What is the difference between Varargs and array in Java?

The three dots can only be used in a method argument, and are called 'varargs'. It means you can pass in an array of parameters without explicitly creating the array. It's worth noting that the varargs are just sugar. The method actually takes an array, plain array.

Is Java Varargs an array?

Every time we use varargs, the Java compiler creates an array to hold the given parameters. In this case, the compiler creates an array with generic type components to hold the arguments. The varargs usage is safe if and only if: We don't store anything in the implicitly created array.

Can you pass an array for Varargs?

If you're passing an array to varargs, and you want its elements to be recognized as individual arguments, and you also need to add an extra argument, then you have no choice but to create another array that accommodates the extra element.

Is it good to use varargs in Java?

Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String. format . The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.


2 Answers

Arrays have been around from the beginning of Java, while varargs are a fairly recent addition. Thus a lot of older code still happily uses arrays.

Note also that calling a generic vararg method with an explicit array parameter may silently produce different behaviour than expected:

public <T> void foo(T... params) { ... }  int[] arr = {1, 2, 3};  foo(arr); // passes an int[][] array containing a single int[] element 

Thus - apart from requiring a lot of effort for no clear benefit - it is not always desirable to replace legacy array parameters with varargs.

Not to mention the cases when you can't, because there is another parameter after the array in the method parameter list:

public void foo(String[] strings, String anotherParam) { ... } 

Reordering the parameters may technically solve this, however it breaks client code.

Update: Effective Java 2nd. Edition, Item 42: Use varargs judiciously explains this in more details, giving also a concrete example: Arrays.asList() was retrofitted in Java5 to have vararg parameters, which inadvertently broke a lot of existing code may cause surprises when using this (now obsolete) idiom to print an array:

System.out.println(Arrays.asList(myArray)); 

Update2: Double checked the source, and it says that the problem occurrs with arrays of primitive types, such as int[]. Before varargs, code like this:

int[] digits = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 4 }; System.out.println(Arrays.asList(digits)); 

would emit a compilation error, because only arrays of reference types could be converted to a List. Since varargs, and retrofitting asList, the code above compiles without warnings, and the unintended result is something like "[[I@3e25a5]".

like image 155
Péter Török Avatar answered Sep 18 '22 14:09

Péter Török


The main reason not to specify everything as varargs is that it doesn't always make sense. For example, if InputStream.read(byte[]) where defined as `read(byte...) then the following call would be valid:

myInputStream.read(0, 1, 2, 3); 

This would create a 4-element byte array, pass it in and then discard it.

like image 24
Joachim Sauer Avatar answered Sep 18 '22 14:09

Joachim Sauer