13

Foo(Object[] args)別の方法で使用されているにもかかわらず、Java で をオーバーロードすることが許可されていないのはなぜFoo(Object... args)でしょうか?

Foo(Object[] args){}

次のように使用されます。

Foo(new Object[]{new Object(), new Object()});

一方、他の形式:

Foo(Object... args){}

次のように使用されます。

Foo(new Object(), new Object());

これには何か理由がありますか?

4

2 に答える 2

25

これについては 15.12.2.5 最も具体的な方法の選択 で説明していますが、非常に複雑です。例: Foo(Number... ints) と Foo(Integer... ints) のどちらかを選択する

下位互換性のために、これらは事実上同じものです。

public Foo(Object... args){} // syntactic sugar for Foo(Object[] args){}

// calls the varargs method.
Foo(new Object[]{new Object(), new Object()});

たとえば、main() を次のように定義できます。

public static void main(String... args) {

それらを異なるものにする方法は、varargs の前に 1 つの引数を取ることです

public Foo(Object o, Object... os){} 

public Foo(Object[] os) {}

Foo(new Object(), new Object()); // calls the first.

Foo(new Object[]{new Object(), new Object()}); // calls the second.

それらはまったく同じではありません。微妙な違いは、配列を可変引数に渡すことはできますが、配列パラメーターを可変引数として扱うことはできないことです。

public Foo(Object... os){} 

public Bar(Object[] os) {}

Foo(new Object[]{new Object(), new Object()}); // compiles fine.

Bar(new Object(), new Object()); // Fails to compile.

さらに、varags は最後のパラメーターである必要があります。

public Foo(Object... os, int i){} // fails to compile.

public Bar(Object[] os, int i) {} // compiles ok.
于 2012-01-12T16:18:05.420 に答える
3

この質問に対する最も直接的な答えは、両方の宣言を使用すると、メソッドのルックアップ ロジックがあいまいになるということです。同じクラスで両方を宣言した場合、次のように呼び出したときに必要なメソッドを特定する方法がありません。

Object[] a = new Object[10];
Foo(a); // array or vararg?

また、Java では、すべてのメソッド呼び出しに対して常に最も具体的なメソッドが存在する必要があります。理由については、Peter's answer を参照してください。

于 2012-01-12T17:30:53.883 に答える