204

我害怕可变参数。我不知道用它们做什么。

另外,让人们随意传递尽可能多的论点感觉很危险。

什么是使用它们的好地方的上下文示例?

4

8 回答 8

154

Varargs对于需要处理不确定数量的对象的任何方法都很有用。一个很好的例子是。格式字符串可以接受任意数量的参数,因此您需要一种机制来传入任意数量的对象。String.format

String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
于 2009-04-20T00:59:20.887 回答
81

一个好的经验法则是:

“将可变参数用于需要 T 数组(无论 T 可能是什么类型)作为输入的任何方法(或构造函数)”。

这将使对这些方法的调用更容易(无需这样做new T[]{...})。

您可以扩展此规则以包含带有List<T>参数的方法,前提是此参数仅用于输入(即,该方法不修改列表)。

此外,我会避免使用f(Object... args),因为它会滑向 API 不明确的编程方式。

示例方面,我在DesignGridLayout中使用过,一次调用可以添加多个JComponent

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

在上面的代码中,add() 方法被定义为add(JComponent... components).

最后,这些方法的实现必须注意它可能被一个空的可变参数调用!如果您想强加至少一个论点,那么您必须使用一个丑陋的技巧,例如:

void f(T arg1, T... args) {...}

我认为这个技巧很难看,因为该方法的实现不如仅T... args在其参数列表中简单。

希望这有助于澄清关于可变参数的观点。

于 2009-04-20T04:06:10.313 回答
34

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.

于 2012-01-02T01:23:21.737 回答
13

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 :)

于 2012-09-25T07:25:01.510 回答
12

Varargs is the feature added in java version 1.5.

Why to use this?

  1. What if, you don't know the number of arguments to pass for a method?
  2. What if, you want to pass unlimited number of arguments to a method?

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

于 2014-10-13T17:09:32.907 回答
6

我也有与可变参数相关的恐惧:

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.

于 2009-04-21T01:03:45.673 回答
1

我经常将可变参数用于可以采用某种过滤器对象的构造函数。例如,我们基于 Hadoop 的系统的很大一部分是基于一个 Mapper,它处理项到 JSON 的序列化和反序列化,并应用多个处理器,每个处理器获取一个内容项并修改并返回它,或者返回 null拒绝。

于 2009-04-20T01:09:01.127 回答
0

In Java doc of Var-Args it is quite clear the usage of var args:

http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html

about usage it says:

"So when should you use varargs? As a client, you should take advantage of them whenever the API offers them. Important uses in core APIs include reflection, message formatting, and the new printf facility. As an API designer, you should use them sparingly, only when the benefit is truly compelling. Generally speaking, you should not overload a varargs method, or it will be difficult for programmers to figure out which overloading gets called. "

于 2016-08-03T22:38:48.207 回答