2008-10-06 88 views
5

考虑以下方法签名:Object数组

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

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

说明:前者以富-对象数组作为参数 - fooMethod(new Foo[]{..}) - 而后者接受任意数量的Foo类型的参数,并将其作为方法内的Foo:s数组显示 - fooMethod(fooObject1, fooObject2, etc...)。

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

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

+0

不知道Java,这是黑暗中的刺,但我认为第一个效率稍微高一点,因为:a)你可能只会传递一个指针,并且b)你会将一个指针传递给内存的一个连续部分。 – 2008-10-06 12:11:30

+0

@monoxide:不,这两种形式都会生成等效的调用字节码,这两种形式都需要构建一个数组才能通过。 – 2008-10-06 12:13:58

+0

第二种形式是第一种语法糖。所以,fooMethod(new Foo(1),new Foo(2))在这里与fooMethod(new Foo [] {new Foo(1),new Foo(2)}相同 – 2008-10-06 12:14:51

回答

12

这些方法实际上是相同的。

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

如果您定义了一个接受Object ...的方法并发送了一个Object []类型的参数,那么就有一个缺陷!

1

后者是在Java 5中引入的,现有的库正逐渐被重新加以支持。您仍然可以使用前者来强调该方法需要2+输入,此外还有对可以使用的位置的限制。

0

确实没有性能问题或类似的问题需要考虑,因此归结为语义。

您是否期望您的方法的调用者有一个Foo的数组准备在手?然后使用Foo []版本。使用可变参数变体来强调有一堆“Foo's”而不是一个数组的可能性。

的可变参数一个典型例子北京时间字符串格式(在C#中,不知道它在Java中怎么叫):

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

在这里,你所期望的参数传递给不同类型的,所以有一个参数数组将是非常不寻常的,因此可变参数变体。使用数组

上的东西另一方面像

string Join(string[] substrings, char concatenationCharacter) 

是完全合理的。

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

3

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

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

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

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

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

相关问题