你什么时候在Java中使用可变参数?

我怕可怕的 我不知道该用什么。

另外,让人们通过尽可能多的论据是很危险的。

什么是一个环境的例子,将是一个很好的地方使用它们?

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

 String.format("This is an integer: %d", myInt); String.format("This is an integer: %d and a string: %s", myInt, myString); 

一个好的经验法则是:

“使用可变参数的任何方法(或构造函数)需要一个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

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

为了调试,我经常使用可变参数输出到日志。

几乎在我的应用程序中的每个类都有一个方法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()的注释。 后来,如果我发现一个bug,我只是取消注释debugPrint()代码,并且我所有的调用debugPrint()都被重新激活。

当然,我可以轻松地避开可变参数,而是执行以下操作:

 private void debugPrint(String msg) { System.out.println(msg); } debugPrint("for assignment " + hwId + ", student " + studentId + ", question " + serialNo + ", the grade is " + grade); 

但是,在这种情况下,当我注释掉debugPrint()代码时,服务器仍然需要经历将每个调用中的所有变量连接到debugPrint()的麻烦,即使对结果字符串没有做任何处理。 但是,如果我使用可变参数,服务器只需要将它们放在一个数组中,然后才意识到它不需要它们。 节省了大量的时间。

当我们不确定在方法中传递的参数的数量时,可以使用可变参数。 它在后台创建一个未指定长度的参数数组,这样的参数在运行时可以被当作一个数组来处理。

如果我们有一个重载的方法来接受不同数量的参数,那么我们可以简单地使用可变参数概念,而不是重载不同的方法。

另外,当参数的类型会发生变化时,使用“Object … test”会简化代码。

例如:

 public int calculate(int...list) { int sum = 0; for (int item : list) { sum += item; } return sum; } 

在这里间接的一个int类型(list)的数组作为参数被传递,并被视为代码中的一个数组。

为了更好地理解这个链接(这在理解这个概念方面帮了我很大的忙): http : //www.javadb.com/using-varargs-in-java

PS:即使我没有把它改过来,也害怕使用可变参数。 但现在我习惯了。 正如它所说的:“我们坚持已知,害怕未知”,所以尽可能地使用它,你也会开始喜欢它:)

可变参数是Java版本1.5中添加的功能。

为什么要使用这个?

  1. 如果你不知道一个方法传递的参数的数量呢?
  2. 如果你想传递无数个参数给一个方法呢?

这是如何工作的?

它使用给定的参数创建一个数组并将数组传递给方法。

例如:

 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

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

如果调用者传入一个明确的数组给该方法(而不是多个参数),您将收到该数组的共享引用。

如果你需要在内部存储这个数组,你可能需要首先克隆它,以避免调用者稍后改变它。

  Object[] args = new Object[] { 1, 2, 3} ; varArgMethod(args); // not varArgMethod(1,2,3); args[2] = "something else"; // this could have unexpected side-effects 

虽然这与传递任何类型的状态可能稍后会改变的对象并没有什么不同,但是由于数组通常(在调用多个参数而不是数组的情况下)由编译器在内部创建一个新的,您可以安全使用,这当然是意想不到的行为。

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

在Var-Args的Java文档中,var args的使用非常清楚:

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

关于使用它说:

“所以什么时候应该使用可变参数?作为一个客户端,只要API提供它们就应该利用它们。核心API的重要用途包括反射,消息格式化和新的printf设施。作为一个API设计者,你应该使用它们只有当这个好处真正引人注目的时候,一般来说,你不应该重载一个可变参数方法,否则程序员很难判断哪个超载被调用。