我可以将数组作为参数传递给Java中具有可变参数的方法吗?

我希望能够创建如下函数:

A类{
私有字符串外部变量;
公共字符串myFormat(字符串格式、对象…参数){
返回String.format(format,extraVar,args);
}
}

这里的问题是args在方法myFormat中被视为Object[],因此是String.format的单个参数,而我希望args中的每个对象都作为新参数传递。因为String.format也是一个带有可变参数的方法,所以这应该是可能的

如果不可能,是否有类似于String.format(String-format,Object[]args)的方法?在这种情况下,我可以使用一个新数组将extraVar前置到args,并将其传递给该方法

是的,aT..只是aT[]的一种语法糖

JLS 8.4.1格式参数

列表中的最后一个形式参数是特殊的;它可能是一个变量arity参数,由类型后面的省略号表示

如果最后一个形式参数是T类型的变量arity参数,则考虑定义T[]类型的形式参数。然后,该方法是一种变量arity方法。否则,它是一种固定算术方法。变量arity方法的调用可能包含比形式参数更多的实际参数表达式。所有与变量arity参数前面的形式参数不对应的实际参数表达式都将被计算,结果存储到一个数组中,该数组将传递给方法调用

下面是一个例子来说明:

公共静态字符串格式(对象…参数){
字符串格式=新字符串(新字符[args.length])
.替换(“\0”和“[%s]”);
返回String.format(格式,args);
}
公共静态void main(字符串…参数){
System.out.println(ezFormat(“A”、“B”、“C”);
//印刷品“A][B][C]”;
}

是的,上面的main方法是有效的,因为同样,String…只是String[]。另外,由于数组是协变的,String[]是一个对象[],因此您也可以通过任何一种方式调用ezFormat(args)

另见


Varargs gotchas#1:传递null

如何解决varargs是相当复杂的,有时它会做一些事情,可能会让您感到惊讶

考虑这个例子:

静态无效计数(对象…objs){
System.out.println(对象长度);
}
计数(空,空,空);//印刷品;3“;
计数(空,空);//印刷品;2“;
计数(空);//抛出java.lang.NullPointerException!!!

由于varargs的解析方式,最后一条语句使用objs=null调用,这当然会导致NullPointerException使用objs.length。如果要为varargs参数提供一个null参数,可以执行以下操作之一:

计数(新对象[]{null});//印刷品;1“;
计数((对象)空);//印刷品;1“;

相关问题

以下是人们在处理varargs时提出的一些问题的示例:


Vararg gotchas#2:添加额外参数

正如您所发现的,以下情况并非如此;“工作”:

String[]myArgs={quot;A",“B",“C"};
System.out.println(ezFormat(myArgs,“Z”);
//印刷品;[[Ljava.lang.String;@13c5982][Z]"

由于varargs的工作方式,ezFormat实际上得到两个参数,第一个是String[],第二个是字符串。如果要将数组传递给varargs,并且希望其元素被识别为单独的参数,并且还需要添加一个额外的参数,那么除了创建另一个容纳额外元素的数组,您别无选择

以下是一些有用的帮助器方法:

静态<T>T[]追加(T[]arr,T lastElement){
最终int N=阵列长度;
arr=java.util.Arrays.copyOf(arr,N+1);
arr[N]=最后一个元素;
返回arr;
}
静态<T>T[]前置(T[]arr,T firstElement){
最终int N=阵列长度;
arr=java.util.Arrays.copyOf(arr,N+1);
系统阵列复制(arr,0,arr,1,N);
arr[0]=第一个元素;
返回arr;
}

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

String[]myArgs={quot;A",“B",“C"};
System.out.println(ezFormat(append(myArgs,“Z”));
//印刷品“A][B][C][Z]”;
System.out.println(ezFormat(前置(myArgs,“Z”));
//印刷品“[Z][A][B][C]”;

Varargs gotchas#3:传递一个基元数组

它不起作用:

int[]myNumbers={1,2,3};
System.out.println(ezFormat(myNumbers));
//印刷品[[[email protected]“];

Varargs仅适用于引用类型。自动装箱不适用于基元数组。以下方法适用:

Integer[]myNumbers={1,2,3};
System.out.println(ezFormat(myNumbers));
//印刷品“[1][2][3]”;

发表评论