在可变参数上
Type...方法参数声明中的构造通常称为varargs。在JLS中,它称为 可变arity 参数。
JLS8.4.1格式参数
列表中的最后一个形式参数是特殊的;它可以是 可变 Arity参数,由类型后面的省略号表示。
如果最后一个形式参数是类型的可变arity参数
T,则考虑定义类型的形式参数T[]。然后,该方法是 可变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"相反,如果没有varargs构造,则必须执行以下操作:
static void g(int[] nums) { for (int num : nums) { System.out.println(num); } }//...g(new int[] { 1, 2, 3 }); // prints "1", "2", "3"可变参数是所谓的语法糖,它向您隐藏了详细信息。
所以,回到你的问题,之间的区别
printMax(double... numbers),并
printmax(doublenumbers[])是第一种是 可变的元数 法,这意味着你可以给它的参数变量号。后者是 固定Arity 方法,这意味着它将接受一个且唯一的参数。
请注意上面关于
T...真的是一个引号的引用
T[]。也就是说,即使使用了varargs,您仍然可以执行以下操作:
f(new int[] { 1, 2, 3 }); // prints "1", "2", "3"在这里,您正在手动创建数组以容纳vararg参数。实际上,如果深入研究代码,您会发现,正如JLS指定的
f那样,实际上确实带有
int[]参数,并且
f(1,2, 3)实现为
f(new int[] { 1, 2, 3 })。也可以看看
- Java语言指南/ varargs
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!!!由于可变参数是如何解决的,最后一条语句调用与
objs =null,这当然会导致
NullPointerException用
objs.length。如果要将一个
null参数赋给varargs参数,则可以执行以下任一操作:
count(new Object[] { null }); // prints "1"count((Object) null); // prints "1"关于何时使用varargs
如上一节所示,可变参数可能很棘手。但是,如果在正确的情况下使用它们,它们可以导致更简洁的代码。
这是来自 有效Java第二版,项目42:明智地使用varargs 的引文(作者强调):
这课很清楚。 不要改造所有带有最终数组参数的方法; 仅 在调用确实对可变长度的值序列进行运算 时才 使用varargs。
varargs不仅会造成混乱,而且成本很高。 实际上,Effective Java 2nd Edition 建议为最常见的使用情况提供固定数量的重载。
假设您确定95%的方法调用具有三个或更少的参数。然后声明该方法的5个重载,每个重载为0到3个普通参数,并在参数数量超过3个时使用单个varargs。
这本书的内容更深入,但是从本质上讲,只有在真正有意义时才应使用varargs。即使在这些情况下,出于性能原因,您可能仍要考虑提供固定的arar重载。
API链接
以下是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[];
相反,您应该将括号放在 type 而不是 标识符上 :
int[] x;
请注意,这也是在上述讨论(例如)中引用数组的方式
T[]
int[]。
相关问题
- 有什么区别
Object[] x
和Object x[]
? int[] myArray
和int myArray[]
Java 之间的区别- 在数组声明
int[] k,i
和int k[],i
- 这些声明导致
i
!的类型不同。
- 这些声明导致


![形式参数类型声明中double…和double []之间的区别 形式参数类型声明中double…和double []之间的区别](http://www.mshxw.com/aiimages/31/569509.png)
