我希望能够创建如下函数:
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]”;