为什么我们不能只使用数组而不是varargs?

时间:2014-12-29 12:48:33

标签: java android arrays variadic-functions

我刚刚遇到varargs,同时学习了android(doInBackground(Type... params)), SO 帖子澄清了它的使用

我的问题是为什么我们不能只使用数组代替varargs

public void foo(String...strings) {  }

我可以通过在数组中打包我的可变数量的参数并将其传递给像这样的方法来替换这种类型的调用

public void foo(String[] alternativeWay){  }

java中main(String[] args)也使用varargs,如果不是,我们如何能够将运行时参数传递给它

请建议varargs的好处或用法,是否还有其他重要信息需要了解varargs

4 个答案:

答案 0 :(得分:13)

之间的唯一区别
foo(String... strings)

foo(String[] strings)

用于调用代码。考虑这个电话:

foo("a", "b");

这对于foo的第一个声明是有效的,并且编译器将发出代码以在执行时创建包含对"a""b"的引用的数组。它的foo的第二个声明有效,因为它不使用varargs。

在任何一种情况下,调用者都可以显式地创建数组:

for(new String[] { "a", "b" }); // Valid for either declaration
  

java中的main(String [] args)也使用varargs,如果没有,我们如何能够将运行时参数传递给它

如果它被写为main(String[] args)则没有;如果你写main(String... args)那就确实如此。这与JVM如何处理它无关,因为 JVM初始化会创建一个带有命令行参数的数组。如果您编写自己的代码以明确调用main,那只会产生影响。

答案 1 :(得分:4)

我们可以使用数组而不是varargs。 Varargs是使用数组的语法糖。但它们使您的代码更紧凑,更易读。比较

private void foo(String... ss) { ... }

private void bar() {
    ...
    foo("One", "Two", "Three");
    ...
}

private void foo(String[] ss) { ... }

private bar() {
    ...
    foo(new String[] { "One", "Two", "Three" });
    ...
}

类似地,我们也不需要菱形运算符(<>,Java 7)或lambdas(Java 8)。但它们确实使代码更具可读性,因此更易于维护。

答案 2 :(得分:2)

varargs的一个优点是需要至少一个参数的方法,例如max。使用varargs,你可以这样做

static int max(int first, int... remaining) {
    int max = first;
    for (int number : remaining)
        max = Math.max(max, number);
    return max;
}

这很棒,因为不可能没有将参数传递给max方法,max的调用代码非常干净:max(2, 4, 1, 8, 9) 。如果数组的长度为0(总是最好避免)或者强制调用者写{{1这真是太丑了。

答案 3 :(得分:2)

因为函数调用看起来更像是函数调用,例如:

new MyAsyncTask().execute("str1", "str2");

看起来比:

更好
new MyAsyncTask().execute(new String[]{"str1", "str2"});

AsyncTask背后没有魔法,通常你不需要传递任何参数,有时你将参数传递给构造函数而不是执行。还有AsyncTask的实现:

https://github.com/roboguice/roboguice/blob/master/roboguice/src/main/java/roboguice/util/SafeAsyncTask.java

根本不使用varargs