我可以将一个数组作为parameter passing给Java中具有可变参数的方法吗?

我想能够创build一个function,如:

class A { private String extraVar; public String myFormat(String format, Object ... args){ return String.format(format, extraVar, args); } } 

这里的问题是, argsmyFormat方法中被当作Object[]处理,因此是String.format的单个参数,而我希望args每个Object都作为新的parameter passing。 由于String.format也是一个可变参数的方法,这应该是可能的。

如果这是不可能的,是否有像String.format(String format, Object[] args) ? 在这种情况下,我可以prepend extraVar使用一个新的数组args并传递给该方法。

可变参数方法function(Object... args)的基础types function(Object[] args) 。 Sun以这种方式增加了可变参数,以保持向后兼容性。

所以你应该能够预先extraVar args和调用String.format(format, args)

是的,一个T...只是一个T[]的语法糖。

JLS 8.4.1格式参数

列表中的最后一个forms参数是特殊的; 它可能是一个可变的参数参数,由types后面的省略号表示。

如果最后一个forms参数是typesT的variablesarity参数,则认为它定义了typesT[]的forms参数。 该方法是一个可变的方法。 否则,这是一个固定的方法。 variablesarity方法的调用可能包含比forms参数更多的实际参数expression式。 所有与variablesarity参数前面的forms参数不相对应的实际参数expression式将被计算,并将结果存储到将传递给方法调用的数组中。

下面是一个例子来说明:

 public static String ezFormat(Object... args) { String format = new String(new char[args.length]) .replace("\0", "[ %s ]"); return String.format(format, args); } public static void main(String... args) { System.out.println(ezFormat("A", "B", "C")); // prints "[ A ][ B ][ C ]" } 

是的,上面的main方法是有效的,因为再次, String...只是String[] 。 另外,因为数组是协变的,所以String[]是一个Object[] ,所以你也可以调用ezFormat(args)

也可以看看

  • Java语言指南/可变参数

Varargs陷阱#1:通过null

可变参数如何解决是相当复杂的,有时它做的事情可能会让你感到惊讶。

考虑这个例子:

 static void count(Object... objs) { System.out.println(objs.length); } count(null, null, null); // prints "3" count(null, null); // prints "2" count(null); // throws java.lang.NullPointerException!!! 

由于如何解决可变参数,最后一个语句调用objs.length objs = null ,这当然会导致与objs.length NullPointerException 。 如果你想给一个variables参数一个null参数,你可以执行以下任一操作:

 count(new Object[] { null }); // prints "1" count((Object) null); // prints "1" 

相关问题

以下是人们在处理可变参数时询问的一些问题的示例:

  • 错误与可变参数和重载?
  • 如何使用可变参数和reflection
  • 最具体的方法与固定/可变参数匹配(可变参数)

Vararg陷阱#2:增加额外的论据

正如你发现的那样,下面的内容不会“起作用”:

  String[] myArgs = { "A", "B", "C" }; System.out.println(ezFormat(myArgs, "Z")); // prints "[ [Ljava.lang.String;@13c5982 ][ Z ]" 

由于varargs的工作方式, ezFormat实际上有两个参数,第一个是String[] ,第二个是String 。 如果将数组传递给可变参数,并且希望将其元素识别为单独的参数,并且还需要添加一个额外的参数,那么您别无select,只能创build另一个容纳额外元素的数组

这里有一些有用的帮手方法:

 static <T> T[] append(T[] arr, T lastElement) { final int N = arr.length; arr = java.util.Arrays.copyOf(arr, N+1); arr[N] = lastElement; return arr; } static <T> T[] prepend(T[] arr, T firstElement) { final int N = arr.length; arr = java.util.Arrays.copyOf(arr, N+1); System.arraycopy(arr, 0, arr, 1, N); arr[0] = firstElement; return arr; } 

现在您可以执行以下操作:

  String[] myArgs = { "A", "B", "C" }; System.out.println(ezFormat(append(myArgs, "Z"))); // prints "[ A ][ B ][ C ][ Z ]" System.out.println(ezFormat(prepend(myArgs, "Z"))); // prints "[ Z ][ A ][ B ][ C ]" 

Varargs陷阱#3:传递一系列基元

它不“工作”:

  int[] myNumbers = { 1, 2, 3 }; System.out.println(ezFormat(myNumbers)); // prints "[ [I@13c5982 ]" 

可变参数只适用于参考types。 自动装箱不适用于原始数组。 以下工作:

  Integer[] myNumbers = { 1, 2, 3 }; System.out.println(ezFormat(myNumbers)); // prints "[ 1 ][ 2 ][ 3 ]" 

传递一个数组是可以的 – 事实上它是相同的

 String.format("%s %s", "hello", "world!"); 

是相同的

 String.format("%s %s", new Object[] { "hello", "world!"}); 

它只是语法糖 – 编译器将第一个转换为第二个,因为基础方法期望vararg参数的数组。

看到

  • 可变参数 – J2SE 1.5文档

jasonmp85是正确的关于传递一个不同的数组到String.format 。 数组的大小一旦构造就不能改变,所以你必须传递一个新的数组而不是修改现有的数组。

 Object newArgs = new Object[args.length+1]; System.arraycopy(args, 0, newArgs, 1, args.length); newArgs[0] = extraVar; String.format(format, extraVar, args);