dat*_*ili 2 java arrays parameter-passing variadic-functions
我有疑问:这两个声明有什么区别?
public static void printMax(double... numbers) { ... }
public static void printmax(double numbers[]) { ... }
Run Code Online (Sandbox Code Playgroud)
是double... numbers一样的double numbers[]吗?
Type...方法参数声明中的构造通常称为varargs.在JLS中,它被称为变量arity参数.
列表中的最后一个正式参数是特殊的; 它可以是一个可变的arity参数,由类型后面的省略号表示.
如果最后一个形式参数是类型的变量arity参数
T,则认为它定义了类型的形式参数T[].然后该方法是可变的arity方法.否则,它是一种固定的arity方法.变量arity方法的调用可能包含比形式参数更多的实际参数表达式.将评估与变量arity参数之前的形式参数不对应的所有实际参数表达式,并将结果存储到将传递给方法调用的数组中.
为了在代码中说明,这是varargs允许您执行的操作:
static void f(int... nums) {
for (int num : nums) {
System.out.println(num);
}
}
//...
f(1,2,3); // prints "1", "2", "3"
Run Code Online (Sandbox Code Playgroud)
相反,如果没有varargs构造,则必须执行以下操作:
static void g(int[] nums) {
for (int num : nums) {
System.out.println(num);
}
}
//...
g(new int[] { 1, 2, 3 }); // prints "1", "2", "3"
Run Code Online (Sandbox Code Playgroud)
varargs是一种所谓的语法糖,可以隐藏你的冗长.
所以,回到你的问题,之间的区别printMax(double... numbers),并printmax(double numbers[])是第一种是可变的元数法,这意味着你可以给它一个可变数量的参数.后者是一个固定的arity方法,这意味着它将接受一个唯一的参数.
注意上面引用的关于T...真的是一个T[].也就是说,即使使用varargs,您仍然可以执行以下操作:
f(new int[] { 1, 2, 3 }); // prints "1", "2", "3"
Run Code Online (Sandbox Code Playgroud)
在这里,您手动创建数组以保存vararg参数.事实上,如果你去反编译代码,你会发现,正如JLS指定的f那样,实际上是接受int[]参数,并f(1, 2, 3)实现为f(new int[] { 1, 2, 3 }).
如何解决varargs是非常复杂的,有时它可能会让你感到惊讶.
考虑这个例子:
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!!!
Run Code Online (Sandbox Code Playgroud)
由于可变参数如何解决,最后的语句调用objs = null,这当然会导致NullPointerException用objs.length.如果要为nullvarargs参数提供一个参数,可以执行以下任一操作:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Run Code Online (Sandbox Code Playgroud)
以下是人们在处理varargs时提出的一些问题的示例:
如前一节所示,varargs可能很棘手.但是,在适当的情况下使用它们可以使代码更加简洁.
以下是Effective Java 2nd Edition的引用,第42项:明智地使用varargs(作者强调):
教训很清楚.不要改进每个具有最终数组参数的方法; 仅当调用确实对可变长度值序列进行操作时才使用varargs.
varargs不仅容易混淆,而且成本也很高.有效的Java第二版实际上建议为最常见的使用场景提供固定的重载.
假设您已确定95%的方法调用具有三个或更少的参数.然后声明方法的五个过载,每个过载一个零到三个普通参数,以及当参数数量超过三个时使用的单个变量.
这本书的深度更深入,但基本上你应该只在实际有意义的时候使用varargs.即使在这些情况下,出于性能原因,您仍可能需要考虑提供固定过载.
以下是varargs有意义的一些示例:
java.util.Arrays.asList(T...)java.util.PrintStream.printf(String format, Object... args)java.lang.reflect.Method.invoke(Object obj, Object... args)请,请不要养成这样声明数组的习惯:
int x[];
Run Code Online (Sandbox Code Playgroud)
您应该使用类型而不是标识符来放置括号:
int[] x;
Run Code Online (Sandbox Code Playgroud)
注意,这也是在上述讨论中引用数组的方式,例如T[] int[],等等.
Object[] x和Object x[]?int[] myArray和之间的区别int myArray[]int[] k,i和int k[],i
i!| 归档时间: |
|
| 查看次数: |
2757 次 |
| 最近记录: |