5

次のメソッドシグネチャを検討してください。

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

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

説明:前者はFooオブジェクトの配列を引数としてfooMethod(new Foo[]{..})取ります---後者はFoo型の任意の量の引数を取り、それらをメソッド内のFoo:sの配列として提示します- fooMethod(fooObject1, fooObject2, etc...)。

両方が定義されている場合、Javaは適合をスローし、それらが重複するメソッドであると主張します。私はいくつかの探偵の仕事をしました、そして最初の宣言が本当にFooオブジェクトの明示的な配列を必要とすることを知りました、そしてそれはそのメソッドを呼び出す唯一の方法です。2番目の方法は、実際には任意の量のFoo引数を受け入れ、Fooオブジェクトの配列も受け入れます。

それで、問題は、後者の方法がより柔軟に見えるので、最初の例を使用する理由はありますか、または私は重要な何かを逃したことがありますか?

4

4 に答える 4

12

これらの方法は実際には同じです。

この機能はvarargsと呼ばれ、コンパイラー機能です。舞台裏は前のバージョンに翻訳されています。

Object ...を受け入れるメソッドを定義し、Object []型のパラメーターを1つ送信した場合、落とし穴があります。

于 2008-10-06T12:11:57.600 に答える
3

Shimiの説明に追加して、varargs構文のもう1つの制限は、varargが最後に宣言されたパラメーターでなければならないことです。したがって、これを行うことはできません。

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

これは、特定のメソッドが持つことができるvarargパラメーターは1つだけであることを意味します。複数の配列を渡したい場合は、そのうちの1つにのみvarargsを使用できます。

実際には、varargsは、argsを配列としてではなく、任意の数の個別の値として扱う場合に最適です。Java5は、それが最も便利なことであるという理由だけで、それらを配列にマップします。

良い例はString.format()です。ここで、varargsは、最初の引数のフォーマットプレースホルダーと照合されます。

于 2008-10-06T12:25:06.560 に答える
1

後者はJava5で導入され、既存のライブラリはそれをサポートするために徐々に作り直されています。前者を使用して、この方法では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)

配列を使用することは完全に合理的です。

また、paramater-listの最後に複数のarray-parametersと1つのvarargパラメーターのみを含めることができることに注意してください。

于 2008-10-06T12:22:43.193 に答える