5

考虑以下方法签名:

public fooMethod (Foo[] foos) { /*...*/ }

public fooMethod (Foo... foos) { /*...*/ }

解释:前者接受一个 Foo 对象数组作为参数 - fooMethod(new Foo[]{..})- 而后者接受任意数量的 Foo 类型参数,并将它们呈现为方法内的 Foo:s 数组 - fooMethod(fooObject1, fooObject2, etc...)。

如果两者都被定义,Java 会抛出一个 fit,声称它们是重复的方法。我做了一些侦探工作,发现第一个声明确实需要一个显式的 Foo 对象数组,这是调用该方法的唯一方法。第二种方式实际上既接受任意数量的 Foo 参数,也接受一个 Foo 对象数组。

所以,问题是,由于后一种方法似乎更灵活,是否有任何理由使用第一个示例,或者我错过了什么重要的东西?

4

4 回答 4

12

这些方法其实都是一样的。

此功能称为可变参数,它是一个编译器功能。幕后是翻译成以前的版本。

如果您定义了一个接受 Object... 的方法并且您发送了一个 Object[] 类型的参数,则会有一个陷阱!

于 2008-10-06T12:11:57.600 回答
3

我想补充 Shimi 的解释,以补充 varargs 语法的另一个限制是 vararg 必须是最后声明的参数。所以你不能这样做:

void myMethod(String... values, int num);

这意味着任何给定的方法只能有一个可变参数。如果你想传递多个数组,你可以只对其中一个使用可变参数。

在实践中,当您将参数视为任意数量的不同值而不是数组时,可变参数处于最佳状态。Java5 将它们映射到一个数组只是因为这是最方便的做法。

一个很好的例子是 String.format()。在这里,可变参数与第一个参数中的格式占位符匹配。

于 2008-10-06T12:25:06.560 回答
1

后者是在 Java 5 中引入的,并且现有的库正在逐渐被重新设计以支持它。您可能仍会使用前者来强调该方法需要 2+ 个输入,而且 ... 可以使用的位置存在限制。

于 2008-10-06T12:10:56.807 回答
0

当然没有性能问题或类似的事情需要考虑,所以它归结为语义。

您是否希望您的方法的调用者手头有一个 Foo 数组?然后使用 Foo[] 版本。使用 varargs 变体来强调使用 Foo 的“一堆”而不是数组的可能性。

varargs 的经典示例是字符串格式(在 C# 中,不知道它在 Java 中是如何调用的):

string Format(string formatString, object... args)

在这里,您希望 args 具有不同的类型,因此拥有一组参数将非常不常用,因此使用 varargs 变体。

另一方面,像

string Join(string[] substrings, char concatenationCharacter)

使用数组是完全合理的。

另请注意,您可以在参数列表的末尾有多个数组参数和一个可变参数参数。

于 2008-10-06T12:22:43.193 回答