考虑以下方法签名:
public fooMethod (Foo[] foos) { /*...*/ }
和
public fooMethod (Foo... foos) { /*...*/ }
说明:前者将一个Foo对象数组作为参数 - fooMethod(new Foo[]{..})
- 而后者采用任意数量的Foo类型的参数,并将它们表示为Foo:s的数组在方法中 - fooMethod(fooObject1, fooObject2, etc...
)。
如果两者都被定义,Java会抛出一个拟合,声称它们是重复的方法。我做了一些侦探工作,发现第一个声明确实需要一个显式的Foo对象数组,这是调用该方法的唯一方法。第二种方式实际上接受任意数量的Foo参数并且还接受Foo对象的数组。
所以,问题是,由于后一种方法似乎更灵活,有没有理由使用第一个例子,或者我错过了什么重要的事情?
答案 0 :(得分:12)
这些方法实际上是一样的。
此功能称为varargs,它是一种编译器功能。在幕后是转换为以前的版本。
如果你定义一个接受Object的方法,你会发现一个陷阱,你发送了一个Object []类型的参数!
答案 1 :(得分:3)
我想补充Shimi的解释,补充说varargs语法的另一个限制是vararg必须是最后声明的参数。所以你不能这样做:
void myMethod(String... values, int num);
这意味着任何给定的方法只能有一个vararg参数。如果要传递多个数组,可以只对其中一个使用varargs。
实际上,当你将args视为任意数量的不同值而不是数组时,varargs处于最佳状态。 Java5将它们映射到数组只是因为这是最方便的事情。
一个很好的例子是String.format()。这里,varargs与第一个参数中的格式占位符匹配。
答案 2 :(得分:1)
后者是在Java 5中引入的,现有的库正逐渐被重新设计以支持它。您可能仍然使用前者强调该方法需要2个以上的输入,并且对可以使用的位置有限制。
答案 3 :(得分:0)
肯定没有性能问题或类似的事情要考虑,所以它归结为语义。
你希望你的方法的调用者有一个Foo的数组就绪吗?然后使用Foo []版本。使用varargs变体来强调拥有一堆Foo而不是数组的可能性。
varargs的经典示例是字符串格式(在C#中,dunno如何在Java中调用):
string Format(string formatString, object... args)
在这里你期望args具有不同的类型,因此拥有一个参数数组将是非常不寻常的,因此varargs变体。
另一方面,像
string Join(string[] substrings, char concatenationCharacter)
使用数组非常合理。
另请注意,在parapater-list的末尾可以有多个数组参数和一个vararg参数。