- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有问题:这两个声明有什么区别?
public static void printMax(double... numbers) { ... }
public static void printmax(double numbers[]) { ... }
双...数字
与双数字[]
相同吗?
最佳答案
方法参数声明中的Type...
构造通常称为可变参数。在 JLS 中,它称为变量数量参数。
The last formal parameter in a list is special; it may be a variable arity parameter, indicated by an elipsis following the type.
If the last formal parameter is a variable arity parameter of type
T
, it is considered to define a formal parameter of typeT[]
. The method is then a variable arity method. Otherwise, it is a fixed arity method. Invocations of a variable arity method may contain more actual argument expressions than formal parameters. All the actual argument expressions that do not correspond to the formal parameters preceding the variable arity parameter will be evaluated and the results stored into an array that will be passed to the method invocation.
为了在代码中说明,这就是 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[])
之间的区别在于,第一个是可变数量方法,这意味着您可以为其提供可变数量的参数。后者是一种固定数量方法,这意味着它将接受一个且唯一的参数。
请注意上面关于 T...
确实是 T[]
的引述。也就是说,即使使用可变参数,您仍然可以执行以下操作:
f(new int[] { 1, 2, 3 }); // prints "1", "2", "3"
这里您手动创建数组来保存可变参数。事实上,如果您反编译代码,您会发现正如 JLS 所指定的那样,f
实际上接受了 int[]
参数,并且 f(1, 2, 3)
实现为 f(new int[] { 1, 2, 3 })
。
如何解析可变参数是相当复杂的,有时它会做一些让你感到惊讶的事情。
考虑这个例子:
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
。如果您想为 varargs 参数提供一个 null
参数,您可以执行以下任一操作:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
以下是人们在处理可变参数时提出的一些问题的示例:
正如上一节所示,可变参数可能很棘手。然而,在正确的情况下使用它们可以产生更加简洁的代码。
这里引用了Effective Java 第二版,第 42 条:明智地使用可变参数(作者强调):
The lesson is clear. Don't retrofit every method that has a final array parameter; use varargs only when a call really operates on a variable-length sequence of values.
可变参数不仅会造成困惑,而且成本高昂。 Effective Java 2nd Edition 实际上建议为最常见的使用场景提供固定数量的重载。
Suppose you've determined that 95 percent of the calls to a method have three or fewer parameters. Then declare five overloadings of the method, one for each with zero through three ordinary parameters, and a single varargs for use when the number of parameters exceed three.
这本书更深入,但本质上你应该只在真正有意义的时候使用可变参数。即使在这些情况下,出于性能原因,您可能仍然需要考虑提供固定数量重载。
以下是一些可变参数有意义的示例:
java.util.Arrays.asList(T...)
java.util.PrintStream.printf(String format, Object... args)
java.lang.reflect.Method.invoke(Object obj, Object... args)
拜托,拜托,不要养成像这样声明数组的习惯:
int x[];
您应该将括号与类型放在一起,而不是与标识符一起放入:
int[] x;
请注意,这也是上面讨论中引用数组的方式,例如T[]
int[]
等
关于java - 形参类型声明中 double... 和 double[] 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2888305/
我是一名优秀的程序员,十分优秀!