2

次のコードがあります

public class HelloWorld {

    public void printData (Test t) {
        System.out.println("Reached 1");
    }

    public void printData(NewTest t) {
        System.out.println("Reached 2");
    }

    public static void main(String args[]) {
        HelloWorld h = new HelloWorld();
        h.printData(null);
    }
}

2つの単純なクラスがあります

class Test {
}

class NewTest extends Test {
}

私が得た出力は Reached 2です

最初の関数ではなく、2 番目の関数が実行のために選択されたのはなぜですか? また、Test と類似の printData() 関数を拡張する別のクラス NewTest2 を作成して同じコードを試したところ、コンパイル時エラーが発生しました。どの関数をいつ実行する必要があるかを選択する規則はありますか?

4

2 に答える 2

6

最初の関数ではなく、2 番目の関数が実行のために選択されたのはなぜですか?

メソッドの取得NewTestはメソッドの取得よりも具体的Testであり、どちらもアクセス可能で適用可能であるためです。

ただし、 の 2 つのサブクラスがあるTest場合、どちらの変換も他方よりも具体的ではないため、呼び出しがあいまいになります。

関連する正確なルールについては、JLS セクション 15.12.2.5を参照してください。

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

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

于 2013-08-16T10:29:07.070 に答える
0

どのIDEを使用していますか? Eclipse では、「h.printData(null)」は次のエラーで赤くマークされます。

メソッド printData(Test) は、タイプ HelloWorld に対してあいまいです。

この場合、次のように null をキャストする必要があります。

"h.printData((テスト)null)"

于 2013-08-16T10:31:52.127 に答える