6

重複の可能性:
NULLパラメーターのメソッドオーバーロード

次のコードはコンパイルされ、正常に動作します。

public class Main
{
    public void temp(Object o)
    {
        System.out.println("The method with the receiving parameter of type Object has been invoked.");
    }

    public void temp(String s)
    {
        System.out.println("The method with the receiving parameter of type String has been invoked.");
    }

    public void temp(int i)
    {
        System.out.println("The method with the receiving parameter of type int has been invoked.");
    }

    public static void main(String[] args)
    {
        Main main=new Main();
        main.temp(null);
    }
}

このコードでは、呼び出されるメソッドは、タイプのパラメーターを受け入れるメソッドです。String

ドキュメントによると。

複数のメンバーメソッドがアクセス可能であり、メソッド呼び出しに適用できる場合は、実行時メソッドディスパッチの記述子を提供するために1つを選択する必要があります。Javaプログラミング言語は、最も具体的な方法が選択されるという規則を使用します。

しかし、プリミティブのパラメーターを受け入れるコード内のメソッドの1つが、次のようなintラッパータイプのパラメーターを受け入れるように変更されたときはわかりません。Integer

public void temp(Integer i)
{
    System.out.println("The method with the receiving parameter of type Integer has been invoked.");
}

コンパイル時エラーが発行されます。

tempへの参照があいまいで、methodoverloadingpkg.Mainのメソッドtemp(java.lang.String)とmethodoverloadingpkg.Mainのメソッドtemp(java.lang.Integer)の両方が一致します

この特定のシナリオでは、プリミティブデータ型でメソッドをオーバーロードすることが合法であるのに、対応するラッパー型ではそうではないように見えるのはなぜですか?

4

3 に答える 3

18

より専門的な「文字列」または「オブジェクト」とは何かと聞かれた場合、あなたは何と言いますか?明らかに「文字列」ですよね?

あなたが尋ねられた場合:より専門的な「文字列」または「整数」は何ですか?答えはありません。どちらもオブジェクトの直交する特殊化ですが、どのように選択できますか?次に、どちらが必要かを明確にする必要があります。たとえば、null参照をキャストすることによって:

question.method((String)null)

プリミティブ型を使用する場合、「null」は参照型であり、プリミティブ型と競合できないため、この問題は発生しません。ただし、参照型を使用する場合、「null」は文字列または整数のいずれかを参照できます(nullは任意の参照型にキャストできるため)。

JLSからのさらに詳細な引用やいくつかの引用については、上記のコメントに投稿した他の質問の回答を参照してください。

于 2012-10-23T23:57:48.260 に答える
3

オーバーロードされたメソッドの引数として渡す場合null、選択されたメソッドは最も特殊なタイプのメソッドであるため、この場合String、最も許容度の高いメソッドではなく、が選択されますObject

//コンパイラーにとってObject、選択は明確です。この場合String、対応するメソッドを呼び出す資格がないため、1つの原因が得られます。intStringintnull

ただし、に変更intするとInteger、コンパイラは混乱します。これは、両方のメソッドがのメソッドStringと同じくらい正確であるためですInteger(階層が直交している)。

そして、コンパイラはランダムに選択することはできません(したくないですか?^^)。

于 2012-10-23T23:57:53.857 に答える
2

main.temp(null);最初に解決する理由を理解しtemp(String s)null引数を使用したJavaメソッドディスパッチtemp(Object o)への古い応答を指摘します。基本的に、リテラルはタイプで<<です。ですから、に近いです。nullnulltypeObjectStringnulltypenullStringObject

さて、nullに近いStringのでInteger、追加test(Integer)するとあいまいになります

于 2012-10-24T00:04:20.847 に答える