我怕可变参数。我不知道该怎么用。
另外,让人们随心所欲地传递争论是很危险的。
什么是使用它们的好地方的上下文示例?
我怕可变参数。我不知道该怎么用。
另外,让人们随心所欲地传递争论是很危险的。
什么是使用它们的好地方的上下文示例?
Answers:
对于需要处理不确定数目的对象的任何方法,Varargs都是有用的。一个很好的例子是。格式字符串可以接受任意数量的参数,因此您需要一种机制来传递任意数量的对象。String.format
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
一个好的经验法则是:
“将varargs用于需要T数组(无论T类型如何)作为输入的任何方法(或构造函数)”。
这将使对这些方法的调用更加容易(无需这样做 new T[]{...}
)。
您可以将此规则扩展为包含带有 List<T>
参数的,前提是该参数仅用于输入(即,列表未被该方法修改)。
此外,我将避免使用 f(Object... args)
它因为它倾向于使用不清楚的API进行编程。
就示例而言,我在DesignGridLayout中使用了它,在其中可以JComponent
在一个调用中添加几个s:
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
在上面的代码中,add()方法定义为add(JComponent... components)
。
最后,此类方法的实现必须考虑到可以使用空vararg调用它的事实。如果要施加至少一个参数,则必须使用一个丑陋的技巧,例如:
void f(T arg1, T... args) {...}
我认为这个技巧很丑陋,因为该方法的实现将比仅仅具有 T... args
在其参数列表中。
希望这有助于阐明有关可变参数的观点。
if (args.length == 0) throw new RuntimeException("foo");
?(因为调用方违反了合同)
void f(T arg1, T... args)
始终确保不带任何参数地调用它,而不必等到运行时。
我经常使用varargs来输出到日志,以进行调试。
我的应用程序中几乎每个类都有一个debugPrint()方法:
private void debugPrint(Object... msg) {
for (Object item : msg) System.out.print(item);
System.out.println();
}
然后,在类的方法中,我将收到如下调用:
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
当我对自己的代码正常工作感到满意时,我将debugPrint()方法中的代码注释掉,以使日志中不会包含过多的无关紧要的信息,但是我可以不对debugPrint()的各个调用进行注释。以后,如果发现错误,则只需取消注释debugPrint()代码,然后重新激活对debugPrint()的所有调用。
当然,我可以轻松避开varargs,而改为执行以下操作:
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
但是,在这种情况下,当我注释掉debugPrint()代码时,即使对结果字符串不做任何处理,服务器仍然必须在每次调用debugPrint()时将所有变量连接在一起的麻烦。但是,如果我使用varargs,则服务器只需在意识到不需要它们之前将它们放入数组即可。节省了大量时间。
当我们不确定方法中要传递的参数数量时,可以使用Varargs。它在后台创建了一个未指定长度的参数数组,此类参数在运行时可以视为数组。
如果我们有一个方法被重载以接受不同数量的参数,那么我们可以简单地使用varargs概念来代替重载该方法的时间。
同样,当参数的类型变化时,使用“ Object ... test”将大大简化代码。
例如:
public int calculate(int...list) {
int sum = 0;
for (int item : list) {
sum += item;
}
return sum;
}
在此,将int类型(列表)的数组作为参数传递,并在代码中视为数组。
为了更好地理解,请访问以下链接(它对我清楚地理解这个概念很有帮助):http : //www.javadb.com/using-varargs-in-java
PS:即使我不熟悉varargs,我也很害怕使用它。但是现在我已经习惯了。就像说的那样:“我们紧贴已知的事物,害怕未知的事物”,因此,尽可能多地使用它,您也将开始喜欢它:)
Varargs是Java 1.5版中添加的功能。
为什么要使用这个?
如何运作?
它使用给定的参数创建一个数组,并将该数组传递给方法。
范例:
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 );
}
}
输出:
2
总和是12
3
总和是21
我也有与varargs相关的恐惧:
如果调用者将显式数组传递给方法(而不是多个参数),则您将收到对该数组的共享引用。
如果需要在内部存储此数组,则可能要先克隆它,以免调用者以后可以更改它。
Object[] args = new Object[] { 1, 2, 3} ;
varArgMethod(args); // not varArgMethod(1,2,3);
args[2] = "something else"; // this could have unexpected side-effects
尽管这与传递其状态可能稍后改变的任何类型的对象并没有什么不同,但是由于数组通常是(在使用多个参数而不是数组的情况下)由编译器在内部创建的一个新鲜的数组,因此您可以放心地使用,这肯定是意料之外的行为。
在Java文档Var-Args中,很清楚var args的用法:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
关于用法,它说:
“因此,什么时候应该使用varargs?作为客户端,只要API提供了它们,就应该利用它们。核心API的重要用途包括反射,消息格式和新的printf工具。作为API设计人员,您应该使用它们只能在收益真正引人注意的情况下,才应谨慎使用。一般而言,您不应重载varargs方法,否则程序员将很难弄清楚将调用哪个重载。