1
class A {

    public void printFirst(int... va) throws IOException{
        System.out.print("A");
    }

    public static void main(String args[]) {
        try {
            new B().printFirst(2);
        } catch (Exception ex) {
        }
    }
}


class B extends A {

    //@Override
    public void printFirst(float... va) throws IOException{
        System.out.print("B");

    }
}

なぜ、あいまいな呼び出しへの参照を示していますか?

4

2 に答える 2

2

varargs表記を削除すると、実際にコンパイルされます。リテラルは、ではなく、2と見なす必要があるため、AのprintFirstがコンパイラによって選択されることを期待します。intfloat

これは、コンパイラがメソッド呼び出し変換を行う方法に関係しているようです。このSOの質問は仕様に含まれていると言っていますが、この質問に関連する受け入れられた回答の一部は矛盾しているようです(拡大変換(intからfloat)をvarargsと組み合わせることができないと言っていますが、後でこれはわかった)。同様の問題がこの質問で議論され、受け入れられた回答は、このケースは実際には特定されていないと結論付けています(残念ながら、議論へのリンクは現在壊れています)。さらに悪いことに、言語ガイドは、このタイプのオーバーロードを回避することを単に提案しています。

于 2013-01-01T20:10:04.867 に答える
0

これはコンパイラのバグのようです。あるコンパイラ(Eclipse)ではコンパイルエラーを再現できますが、別のコンパイラ()では再現できませんjavac。後者は正しいと思います。

Java言語仕様JavaSE7 Editionの§15.12.2.5「最も具体的な方法の選択」によると、表示されるコンパイルエラーは、「最も具体的な方法がない場合にのみ発生するはずです。2つまたは最大限に具体的なより多くのメソッド」(およびその他のさまざまな制限)。B.printFirst(float...)しかし、ここではそうではありません。あなたの場合、メソッドは最大限に具体的ではありません。なぜなら、メソッドは「アクセス可能で適用可能であり、厳密に具体的であり、適用可能でアクセス可能な他のメソッドがない場合」であるためです。のサブタイプであり、のサブタイプではないため、caseは厳密に具体的です。A.printFirst(int...)intfloatfloatint

ちなみに、あなたclass Bはおそらく赤いニシンです。Eclipseでは、少なくとも、次のように記述するだけで同じコンパイルエラーをトリガーできます。

class A
{
    public static void printFirst(float... va)
        { System.out.print("float..."); }
    public static void printFirst(int... va)
        { System.out.print("int..."); }
    public static void main(String args[])
       { printFirst(2); }
}
于 2013-01-02T01:39:16.963 に答える