16

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

以下のコードでは、出力は次のとおりです。

タイプのパラメータを持つメソッドを削除するとString、出力は次のようになります。

物体

パラメータタイプが完全に一致しない場合にメソッドのオーバーロードがどのように機能するかは知っていますが、nullObjectをパラメータとして処理する方法を理解できませんString

これの説明は何ですか?

class C {

    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }

    public static void main(String[] args) {
        m1(null);
    }
}
4

5 に答える 5

17

Java仕様のセクション15.12.2.5に従って、常に最も具体的な方法を使用します。

イントロはそれについてかなり具体的です:

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

非公式の直感では、最初のメソッドによって処理された呼び出しがコンパイル時の型エラーなしで他のメソッドに渡される可能性がある場合、1つのメソッドは別のメソッドよりも具体的です。

一般的に言えば、少なくともコードの可読性のためには、可能な限り明示的にすることが常に最善です。null呼び出したい署名に一致するタイプにキャストすることができます。しかし、それは間違いなく疑わしい慣行です。これは、誰もがこのルールを知っていることを前提としており、コードを読みにくくします。

しかし、それは良い学術的な質問なので、私はあなたの質問を+1します。

于 2012-07-24T16:46:59.127 に答える
8

複数のオーバーロードがシグニチャに一致する場合、Javaはそれらの中から最も具体的なメソッドを選択します。

の値はとの両方に一致nullしますが、のサブクラスであるため、選択されます。クラス階層にの兄弟を含む別のオーバーロードを追加すると、コンパイルエラーが発生します。\ObjectStringStringObjectStringString

// DOES NOT COMPILE
class C {
    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }
    static void m1(Integer x) {
        System.out.print("Integer");
    }
    public static void main(String[] args) {
        m1(null);
    }
}

これは、コード例についてある程度説明している投稿へのリンクです。

于 2012-07-24T16:48:10.093 に答える
5

パラメータとして渡すときに、特定のオーバーロードされたメソッドの呼び出しを強制する必要がある場合はnull、次のようにキャストする必要があります。

m1((String)null);

これを行うことにより、メソッドの正しいオーバーロードバージョンを呼び出していることを確認します。

于 2012-07-24T16:46:27.123 に答える
2

null呼び出したい関数をJavaに指示するには、のタイプを設定する必要があります。

つまり、パラメータを使用m1((Object) null);して実装を呼び出し、もう一方の実装を呼び出します。Objectm1((String) null);

于 2012-07-24T16:46:45.957 に答える
1

1. Stringもオブジェクトであるため、実行時にどのメソッドを呼び出すかJVM混乱します。

2.実行時に呼び出すメソッドを指定する場合は、明示的にキャストすることでこれを行うことができます

例えば:

m1((String)null);
于 2012-07-24T16:49:41.577 に答える