Java 方法签名中的对象数组
考虑以下方法签名:Java 方法签名中的对象数组,java,arrays,methods,Java,Arrays,Methods,考虑以下方法签名: public fooMethod (Foo[] foos) { /*...*/ } 及 说明:前者接受一个Foo对象数组作为参数-fooMethod(new Foo[]{..}),而后者接受任意数量的Foo类型的参数,并在方法-fooMethod(foooobject1、foooobject2等)中将它们表示为Foo:s数组 如果两者都定义了,Java就会抛出一个错误,声称它们是重复的方法。我做了一些调查工作,发现第一个声明确实需要一个Foo对象的显式数组,这是调用该方法的
public fooMethod (Foo[] foos) { /*...*/ }
及
说明:前者接受一个Foo对象数组作为参数-fooMethod(new Foo[]{..})
,而后者接受任意数量的Foo类型的参数,并在方法-fooMethod(foooobject1、foooobject2等)中将它们表示为Foo:s数组
如果两者都定义了,Java就会抛出一个错误,声称它们是重复的方法。我做了一些调查工作,发现第一个声明确实需要一个Foo对象的显式数组,这是调用该方法的唯一方法。第二种方法实际上既接受任意数量的Foo参数,也接受Foo对象数组
因此,问题是,既然后一种方法看起来更灵活,那么有没有理由使用第一个示例,或者我遗漏了什么重要的东西?后一种方法是在Java 5中引入的,现有的库正在逐步进行修改以支持它。您可能仍然使用前者来强调该方法需要2+个输入,另外,在。。。可以使用。这些方法实际上是相同的
这个特性称为varargs,它是一个编译器特性。幕后是翻译成前一个版本
如果您定义一个接受对象的方法,就会有一个陷阱。。。您发送了一个Object[]类型的参数 > P>当然没有性能问题或类似的事情要考虑,所以归结为语义。
您是否希望方法的调用方手头有一个Foo数组?然后使用Foo[]版本。使用varargs变量来强调使用一组Foo而不是数组的可能性
varargs的一个经典示例是字符串格式(在C#中,不知道它在Java中是如何调用的):
在这里,您希望args具有不同的类型,因此拥有一个参数数组是非常不寻常的,因此使用varargs变量
另一方面,在类似
string Join(string[] substrings, char concatenationCharacter)
使用数组是完全合理的
还要注意,您可以有多个数组参数,并且在参数列表的末尾只能有一个vararg参数。我想补充Shimi的解释,以补充varargs语法的另一个限制是vararg必须是最后声明的参数。所以你不能这么做:
void myMethod(String... values, int num);
这意味着任何给定的方法只能有一个vararg参数。如果要传递多个数组,则只能对其中一个数组使用varargs
实际上,当您将参数视为任意数量的不同值而不是数组时,varargs处于最佳状态。Java5将它们映射到一个数组只是因为这是最方便的事情
一个很好的例子是String.format()。在这里,vararg与第一个参数中的格式占位符相匹配。不懂Java,这是一个暗中操作,但我认为第一个更有效,因为:a)可能只传递一个指针,b)将传递一个指向内存连续部分的指针。@n:否,这两种形式都生成等价的调用字节码,这两种形式都需要构建一个数组来传递。第二种形式只是第一种形式的语法糖。因此,这里的fooMethod(new Foo(1),new Foo(2))与fooMethod(new Foo[]{new Foo(1),new Foo(2)})完全相同,只是它不强调排序,实际上允许0或1个输入(除非文档中另有规定,在这种情况下,变量形式同样好)(对于可变模式)或(对象[])数组(对于非可变模式)。:-)
string Join(string[] substrings, char concatenationCharacter)
void myMethod(String... values, int num);