I\'m afraid of varargs. I don\'t know what to use them for.
Plus, it feels dangerous to let people pass as many arguments as they want.
What\'s an example
Varargs is the feature added in java version 1.5.
Why to use this?
How this works?
It creates an array with the given arguments & passes the array to the method.
Example :
public class Solution {
public static void main(String[] args) {
add(5,7);
add(5,7,9);
}
public static void add(int... s){
System.out.println(s.length);
int sum=0;
for(int num:s)
sum=sum+num;
System.out.println("sum is "+sum );
}
}
Output :
2
sum is 12
3
sum is 21
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.
If we have a method which is overloaded to accept different number of parameters, then instead of overloading the method different times, we can simply use varargs concept.
Also when the parameters' type is going to vary then using "Object...test" will simplify the code a lot.
For example:
public int calculate(int...list) {
int sum = 0;
for (int item : list) {
sum += item;
}
return sum;
}
Here indirectly an array of int type (list) is passed as parameter and is treated as an array in the code.
For a better understanding follow this link(it helped me a lot in understanding this concept clearly): http://www.javadb.com/using-varargs-in-java
P.S: Even I was afraid of using varargs when I didn't knw abt it. But now I am used to it. As it is said: "We cling to the known, afraid of the unknown", so just use it as much as you can and you too will start liking it :)
I use varargs frequently for constructors that can take some sort of filter object. For example, a large part of our system based on Hadoop is based on a Mapper that handles serialization and deserialization of items to JSON, and applies a number of processors that each take an item of content and either modify and return it, or return null to reject.
A good rule of thumb would be:
"Use varargs for any method (or constructor) that needs an array of T (whatever type T may be) as input".
That will make calls to these methods easier (no need to do new T[]{...}
).
You could extend this rule to include methods with a List<T>
argument, provided that this argument is for input only (ie, the list is not modified by the method).
Additionally, I would refrain from using f(Object... args)
because its slips towards a programming way with unclear APIs.
In terms of examples, I have used it in DesignGridLayout, where I can add several JComponent
s in one call:
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
In the code above the add() method is defined as add(JComponent... components)
.
Finally, the implementation of such methods must take care of the fact that it may be called with an empty vararg! If you want to impose at least one argument, then you have to use an ugly trick such as:
void f(T arg1, T... args) {...}
I consider this trick ugly because the implementation of the method will be less straightforward than having just T... args
in its arguments list.
Hopes this helps clarifying the point about varargs.
I use varargs frequently for outputting to the logs for purposes of debugging.
Pretty much every class in my app has a method debugPrint():
private void debugPrint(Object... msg) {
for (Object item : msg) System.out.print(item);
System.out.println();
}
Then, within methods of the class, I have calls like the following:
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
When I'm satisfied that my code is working, I comment out the code in the debugPrint() method so that the logs will not contain too much extraneous and unwanted information, but I can leave the individual calls to debugPrint() uncommented. Later, if I find a bug, I just uncomment the debugPrint() code, and all my calls to debugPrint() are reactivated.
Of course, I could just as easily eschew varargs and do the following instead:
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
However, in this case, when I comment out the debugPrint() code, the server still has to go through the trouble of concatenating all the variables in every call to debugPrint(), even though nothing is done with the resulting string. If I use varargs, however, the server only has to put them in an array before it realizes that it doesn't need them. Lots of time is saved.
I have a varargs-related fear, too:
If the caller passes in an explicit array to the method (as opposed to multiple parameters), you will receive a shared reference to that array.
If you need to store this array internally, you might want to clone it first to avoid the caller being able to change it later.
Object[] args = new Object[] { 1, 2, 3} ;
varArgMethod(args); // not varArgMethod(1,2,3);
args[2] = "something else"; // this could have unexpected side-effects
While this is not really different from passing in any kind of object whose state might change later, since the array is usually (in case of a call with multiple arguments instead of an array) a fresh one created by the compiler internally that you can safely use, this is certainly unexpected behaviour.