你什么时候在 Java 中使用可变参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/766559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When do you use varargs in Java?
提问by Harry Quince
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 of a context that would be a good place to use them?
什么是使用它们的好地方的上下文示例?
采纳答案by Andy White
Varargsare usefulfor 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.
可变参数对于需要处理不确定数量对象的任何方法都很有用。一个很好的例子是String.format
。格式字符串可以接受任意数量的参数,因此您需要一种机制来传入任意数量的对象。
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
回答by Kevin Peterson
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.
我经常将可变参数用于可以采用某种过滤器对象的构造函数。例如,我们基于 Hadoop 的系统的很大一部分基于一个 Mapper,它处理项目到 JSON 的序列化和反序列化,并应用许多处理器,每个处理器都获取一个内容项目并修改并返回它,或者返回 null拒绝。
回答by jfpoilpret
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".
“对需要 T 数组(无论 T 类型如何)作为输入的任何方法(或构造函数)使用可变参数”。
That will make calls to these methods easier (no need to do new T[]{...}
).
这将使调用这些方法更容易(无需执行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).
您可以扩展此规则以包含带有List<T>
参数的方法,前提是此参数仅用于输入(即,该方法不会修改列表)。
Additionally, I would refrain from using f(Object... args)
because its slips towards a programming way with unclear APIs.
此外,我会避免使用,f(Object... args)
因为它会滑向 API 不明确的编程方式。
In terms of examples, I have used it in DesignGridLayout, where I can add several JComponent
s in one call:
在示例方面,我在DesignGridLayout 中使用了它,在那里我可以JComponent
在一次调用中添加几个:
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
In the code above the add() method is defined as add(JComponent... components)
.
在上面的代码中, add() 方法被定义为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:
最后,这些方法的实现必须注意它可能会被一个空的 vararg 调用的事实!如果您想强加至少一个论点,那么您必须使用一种丑陋的技巧,例如:
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.
我认为这个技巧很丑,因为该方法的实现不如仅T... args
在其参数列表中那么简单。
Hopes this helps clarifying the point about varargs.
希望这有助于澄清有关可变参数的观点。
回答by Thilo
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.
虽然这与传入任何类型的对象(其状态可能会在以后更改)并没有真正不同,因为数组通常是(在使用多个参数而不是数组的调用的情况下)由编译器在内部创建的新对象,您可以安全地使用,这肯定是意想不到的行为。
回答by bob
I use varargs frequently for outputting to the logs for purposes of debugging.
我经常使用可变参数输出到日志以进行调试。
Pretty much every class in my app has a method debugPrint():
我的应用程序中几乎每个类都有一个方法 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.
当我对我的代码工作感到满意时,我会在 debugPrint() 方法中注释掉代码,以便日志不会包含太多无关和不需要的信息,但我可以不注释对 debugPrint() 的各个调用。稍后,如果我发现错误,我只需取消对 debugPrint() 代码的注释,然后重新激活我对 debugPrint() 的所有调用。
Of course, I could just as easily eschew varargs and do the following instead:
当然,我可以轻松地避开 varargs 并执行以下操作:
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.
然而,在这种情况下,当我注释掉 debugPrint() 代码时,服务器仍然必须经历在每次调用 debugPrint() 时连接所有变量的麻烦,即使对结果字符串没有做任何事情。但是,如果我使用可变参数,服务器只需将它们放入一个数组中,然后它就会意识到它不需要它们。节省了很多时间。
回答by Sarvan
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.
如果我们有一个方法被重载以接受不同数量的参数,那么我们可以简单地使用 varargs 概念而不是重载方法不同的时间。
Also when the parameters' type is going to vary then using "Object...test" will simplify the code a lot.
此外,当参数的类型将发生变化时,使用“Object...test”将大大简化代码。
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.
这里间接地将 int 类型(列表)的数组作为参数传递,并在代码中将其视为数组。
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
为了更好地理解,请点击此链接(它对我清楚地理解这个概念有很大帮助):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 :)
PS:当我不知道它时,即使我害怕使用可变参数。但现在我已经习惯了。俗话说:“我们执着于已知,害怕未知”,所以尽可能多地使用它,你也会开始喜欢它:)
回答by Arun Prakash
Varargs is the feature added in java version 1.5.
Varargs 是 Java 1.5 版中添加的功能。
Why to use this?
为什么要用这个?
- What if, you don't know the number of arguments to pass for a method?
- 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
2
sum is 12
总和是 12
3
3
sum is 21
总和是 21
回答by Surendra
In Java doc of Var-Args it is quite clear the usage of var args:
在 Var-Args 的 Java 文档中,var args 的用法非常清楚:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
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. "
“那么你什么时候应该使用可变参数?作为客户,你应该在 API 提供它们时利用它们。核心 API 中的重要用途包括反射、消息格式化和新的 printf 工具。作为 API 设计者,你应该使用它们谨慎地,只有当好处真正引人注目时。一般来说,你不应该重载 varargs 方法,否则程序员很难弄清楚调用的是哪个重载。”