問題タブ [ambiguous-call]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 正確なオーバーロード解決手順 - f(int... arg) および f(long... arg) に対する f(1) 呼び出しがあいまいではないのはなぜですか?
これらが当てはまると思います:
JLS 15.12.2.4 . フェーズ 3: 可変アリティ呼び出しによって適用可能なメソッドを特定する
JLS 15.12.2.5。 最も具体的な方法の選択
しかし、JLS 言語はとても複雑で、私にはその要点が理解できません。
オーバーロード解決プロセス全体のすべての詳細 (正確なシーケンス - どの引数が試行されるか) については答えが説明されていませんでしたが、私はその 1 つを理解しているようです (これはここで既に回答されています)。とにかく、私の質問は主に 2 番目のコード スニペットにあります(int.. vs long...)。しかし、上記のスニペットの詳細に進みましょう。
f((short)1)
- 完全に一致しないため、プリミティブ short が最初に拡張され (一致が見つからない)、次に short が Short にボックス化され (完全な一致が見つからない)、Short が拡張されます (Number、Object) - 一致せず、今度は第 3 フェーズ (varargs) になります。 =>次のことを試みます:
- 短い... (完全に一致しない => プリミティブ拡張を試す)
- int... (正確な一致が見つかりましたが、停止しないで、さらに検索してください! )
- long...、float...、double... (一致しない => ボクシングを試す)
- 短い...、数値...、オブジェクト...
他に一致するものが見つからないため、コンパイルは問題ありません。
f(1)
- 完全一致がないため、プリミティブ int が最初に拡張され (一致が見つからない)、次に int が Integer にボックス化され (完全一致が見つからない)、Integer が拡張されます (Number, Object) - 一致せず、今度は第 3 フェーズ (varargs) =>次のことを試みます:
- int... (正確な一致が見つかりましたが、停止しないで、さらに検索してください! )
- long...、float...、double... (一致しない => ボクシングを試す)
- 整数... (あいまいになりました)、数値...、オブジェクト...
一致する候補が 2 つ見つかったため、コンパイル エラーが発生しました。
f(byte)
- 第 3 フェーズ (varargs) => 以下が試行されます。
- バイト... (一致しない => プリミティブ拡張を試す)
- short..., int... (一致が見つかりましたが、さらに調べてください), long... (あいまいなエラーになるはずですが、そうではありません! ), float..., double... (これでボクシングも行いますコンパイルエラー「あいまい」にフラグを立てるために、より多くの可能な一致を探すためのその後の参照の拡大)
- バイト...、数値...、オブジェクト...
一致する可能性のあるものが 2 つ見つかったため、コンパイル エラーになります (ただし、そうではありません)。
私の推測では、4 つの手順 (完全なプリミティブ マッチ、プリミティブの拡大、ボックス化と正確な参照の一致、参照の拡大) があり、コンパイラは、一部の手順で一致が見つかった場合に停止します (手順は続行されません)。手順。この場合、コンパイラは手順 2 で停止し (int... のみ一致しますが、long... は一致しません)、手順 3 と 4 は一致しませんでした。
SOに関する上記の回答は、次の基準を提供します。
1 つのパラメーターが他のパラメーターよりも具体的であるためには、そのパラメーターの型が他のメソッドのパラメーターのサブタイプである必要があります。
参照型では機能する可能性がありますが、プリミティブの場合は機能しません。
私は15.12.2を理解しているようです。コンパイル時のステップ 2: メソッド シグネチャを決定します。しかし、私の場合、「第 3 フェーズ (§15.12.2.4) では、オーバーロードを可変アリティ メソッド、ボクシング、およびアンボクシングと組み合わせることができます。」-しかし、これの詳細が問題です。