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

问题描述 投票:8回答:4

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

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

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

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

public void foo(String[] alternativeWay){  }

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

请建议varargs的好处或使用,还有什么重要的了解varargs

java android arrays variadic-functions
4个回答
14
投票

唯一的区别

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,那只会有所不同。


5
投票

我们可以使用数组而不是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
投票

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

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


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)。没有varargs,强制执行至少应该传递一个数字的条件的唯一方法就是在运行时抛出异常,如果数组长度为0(总是最好避免)或者强制调用者写max(2, new int[] {4, 1, 8, 9})这是真的丑陋。

© www.soinside.com 2019 - 2024. All rights reserved.