7

次の構造のコードを書きました。

public void method(int x) {
    //...
}

public void method(int x, String... things) {
    //...
}

これがコンパイルされたことにかなり驚きました。

method(3);

次に、最初のものを選択します。明らかに、これはある意味で選択するのが自然な方法ですが、最初のメソッドが存在しない場合、これは (空の varargs 配列を使用して) 2 番目のメソッドを呼び出す合理的な方法です。確かに、あいまいであると見なされ、コンパイル時にエラーが発生するはずですか?

それとも、これは特別なケースとして扱われますか?

新しいメソッドを追加すると既存のコードが壊れる可能性があり、それはあまり幸せな状態ではないため、そのように扱うのは間違っているようです。

(最初のメソッドが 2 番目のメソッドを含むサブクラスの新しいメソッドとして追加された場合に、最終的にどちらを呼び出すかはわかりません...)

4

2 に答える 2

10

Java 言語仕様の第 15 章によると、適用可能なメソッドの検索は 3 つのフェーズで行われます。

最初のフェーズ (§15.12.2.2) では、ボックス化またはボックス化解除の変換、または可変アリティ メソッド呼び出しの使用を許可せずに、オーバーロードの解決を実行します。このフェーズで適用可能なメソッドが見つからない場合、処理は 2 番目のフェーズに進みます。

したがって、最初の方法はすでに第 1 段階で適用可能であると考えられます。残りのフェーズはスキップされます。String... メソッドは、第 3 フェーズでのみ考慮されます。

第 3 フェーズ (§15.12.2.4) では、オーバーロードを可変アリティ メソッド、ボックス化、およびボックス化解除と組み合わせることができます。

于 2015-08-12T14:21:15.130 に答える