编程语言
首页 > 编程语言> > java – 形式参数类型声明中double …和double []之间的区别

java – 形式参数类型声明中double …和double []之间的区别

作者:互联网

我有疑问:这两个声明有什么区别?

 public static void printMax(double... numbers) { ... }

 public static void printmax(double numbers[])  { ... }

是双…数字与双数[]相同?

解决方法:

在varargs

方法参数声明中的Type …构造通常称为varargs.在JLS中,它被称为变量arity参数.

JLS 8.4.1 Format parameters

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 type T[]. 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"

varargs是一种所谓的语法糖,可以隐藏你的冗长.

所以回到你的问题,printMax(double …数字)和printmax(double numbers [])之间的区别在于第一个是变量arity方法,这意味着你可以给它一个可变数量的参数.后者是一个固定的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 language guide/varargs

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!!!

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

count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"

相关问题

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

> bug with varargs and overloading?
> How to work with varargs and reflection
> Most specific method with matches of both fixed/variable arity (varargs)

何时使用varargs

如前一节所示,varargs可能很棘手.但是,在适当的情况下使用它们可以使代码更加简洁.

以下是Effective Java 2nd Edition的引用,第42项:明智地使用varargs(作者强调):

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.

varargs不仅令人困惑,而且成本也很高.有效的Java第二版实际上建议为最常见的使用场景提供固定的重载.

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.

这本书的深度更深入,但基本上你应该只在实际有意义的时候使用varargs.即使在这些情况下,出于性能原因,您仍可能需要考虑提供固定过载.

相关问题

> Java’s varargs performance.

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[];

您应该使用类型而不是标识符来放置括号:

int[] x;

注意,这也是在上述讨论中引用数组的方式,例如, T [] int []等

相关问题

> Is there any difference between Object[] x and Object x[] ?
> Difference between int[] myArray and int myArray[] in Java
> in array declaration int[] k,i and int k[],i

>这些声明导致i的类型不同!

标签:java,arrays,parameter-passing,variadic-functions
来源: https://codeday.me/bug/20190927/1824574.html