14

次のコード スニペットがあります。

public static void foo(Object x) {
    System.out.println("Obj");
}
public static void foo(String x) {
    System.out.println("Str");
}

私が電話した場合foo(null)、なぜあいまいさがないのですか?foo(String x)プログラムが代わりに呼び出すのはなぜfoo(Object x)ですか?

4

4 に答える 4

21

プログラムがfoo(String x)代わりに呼び出す理由foo(Object x)

これは、Stringclass が から拡張されているObjectため、 により固有であるためObjectです。したがって、コンパイラはそのメソッドを呼び出すことを決定します。Compiler は常に、呼び出す最も具体的なメソッドを選択することに注意してください。JLSのセクション15.12.5を参照してください

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

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

Stringただし、パラメータ - 、およびを持つ 2 つのメソッドがある場合、コンパイラは非共変型であるため、どちらがより具体的であるかを判断できないため、エラーIntegerが発生します。ambiguitynull

于 2013-02-09T15:15:28.943 に答える
5
  1. の型nullは、定義上、他のすべての参照型のサブタイプです。JLS 4.1 の引用:

    null 参照は、常に任意の参照型への拡大参照変換を受けることができます。

  2. 呼び出しに含まれるメソッド シグネチャの解決は、互換性のあるすべてのシグネチャのセットの中で最も具体的なシグネチャの原則に従います。(JLS 15.12.2.5. 最も具体的な方法の選択)。

まとめると、これはString、例でオーバーロードが選択されていることを意味します。

于 2013-02-09T15:21:10.797 に答える
4

最も具体的なメソッドを呼び出しています。

String は Object のサブクラスであるため、String は Object よりも「より具体的」です。

于 2013-02-09T15:18:40.130 に答える
2

引数が両方のパラメーターに対して有効な 2 つのメソッドから選択する場合、コンパイラーは常に最も具体的なパラメーターを一致として選択します。この場合、はおよびnullとして扱えるリテラルです。はより具体的であり、のサブクラスであるため、コンパイラはそれを使用します。ObjectStringStringObject

于 2013-02-09T15:17:12.940 に答える