关于java:varargs和’…’参数

varargs and the '…' argument

考虑方法声明:

1
String.format(String, Object ...)

Object ...参数只是对Objects数组的引用。有没有一种方法可以将此方法与对实际Object数组的引用一起使用?如果我将一个Object数组传递给...参数,结果参数值将是一个二维数组,因为Object[]本身就是一个Object

1
2
Object[] params = ....; // Make the array (for example based on user-input)
String s = String.format("%S has %.2f euros", params);

因此,数组的第一个组件(在String.format方法中使用)将是一个数组,他将生成:

1
[class.getName() +"@" + Integer.toHexString(hashCode())]

然后是一个错误,因为数组大小是1。

大胆的顺序才是真正的问题。这是第二个问题:...数组/参数是否有名称?


来自varargs上的文档:

The three periods after the final
parameter's type indicate that the
final argument may be passed as an
array or as a sequence of arguments.

所以可以传递多个参数或一个数组。

以下工作正常:

1
2
3
4
5
6
7
class VarargTest {
  public static void main(String[] args) {
    Object[] params = {"x", 1.2345f};
    String s = String.format("%s is %.2f", params);
    System.out.println(s); // Output is: x is 1.23
  }
}


您只需传递一个数组:

1
2
3
4
5
public void foo(String... args) {
}

String args[] = new String[10];
foo(args);


您所描述的情况将非常罕见:大多数情况下,您的varargs项目将是Strings,或数字,或Widgets…它们通常是Objects(可以是任何东西)或数组。

但是,如果varargs参数是一组Objects或数组类型,那么您的问题就出现了:您可以将它传递给一个数组,然后编译器如何知道您是要传递一个数组(您提供的数组)还是应该将一系列1项放入一个数组中?

快速测试显示答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TestClass {
    public static void main(String[] args) {
        Object anObject = new Object();
        Object[] anArray = new Object[] {anObject, anObject};
        System.out.println("object1 =" + anObject);
        System.out.println("array1 =" + anArray);
        takesArgs();
        takesArgs(anObject, anObject);
        takesArgs(anArray); // is this the same as array1?
        takesArgs(anArray, anArray);
    }

    public static void takesArgs(Object... stuff) {
        System.out.println("The array was" + stuff);
    }
}

执行结果(您的确切数字会有所不同:

1
2
3
4
5
6
object1 = java.lang.Object@3e25a5
array1 = [Ljava.lang.Object;@19821f
The array was [Ljava.lang.Object;@addbf1
The array was [Ljava.lang.Object;@42e816
The array was [Ljava.lang.Object;@19821f
The array was [Ljava.lang.Object;@9304b1

因此,答案是,在不明确的情况下,它将传递的内容视为数组,而不是创建一个新的数组来包装它。这是有意义的,因为如果你想要其他的解释,你可以自己把它包装成一个数组。