10

以下は、3 つのオーバーロードされたコンストラクターを持つ Java クラスです。

public class Test {

    public Test(Object i){
        System.out.println("Object invoked");
    }

    public Test(String i){
        System.out.println("String invoked");
    }

    public Test(int k){
        System.out.println("Integer invoked");
    }

    public static void main(String[] args) throws Exception {

        Test t = new Test(null);
    }
}

クラスの新しいインスタンスの作成中に null 値が渡された場合、どのコンストラクターが呼び出されますか? 理由は何ですか ?

4

2 に答える 2

11

Java は常に、渡された引数に適用できる最も具体的なメソッド (またはコンストラクター) を選択します。この場合、それはStringコンストラクタです --StringのサブクラスですObject

持っていたらどうなるか考えてみてください

new Test("some string")

ここでは、コンストラクターObjectとコンストラクターの両方Stringを適用できます。結局のところ、引数は anObjectと a の両方Stringです。ただしString、コンストラクターよりも具体的でありObject、引数が与えられても適用できるため、コンストラクターが呼び出されることは明らかです。

null違いはありません。これら 2 つのコンストラクターは引き続き適用可能であり、同じ理由でコンストラクターが 1Stringつよりも選択されます。Object

ここで、同等に「特定の」コンストラクターが 2 つ存在する場合 (たとえば、Integerコンストラクターがある場合)、 を呼び出したときにコンパイル エラーが発生しますTest(null)

これについては、 JLS §15.12.2で詳しく説明されています。

2 番目の手順では、メンバー メソッドの前の手順で決定された型を検索します。このステップでは、メソッドの名前と引数式の型を使用して、アクセス可能で適用可能なメソッド、つまり、指定された引数で正しく呼び出すことができる宣言を見つけます。

そのような方法が複数ある場合があります。その場合、最も具体的な方法が選択されます。最も具体的なメソッドの記述子 (署名と戻り値の型) は、メソッドのディスパッチを実行するために実行時に使用されるものです。

最も具体的なメソッドを決定する明示的なプロセスは、JLS §15.12.2.5で概説されています。

于 2013-09-14T15:02:05.290 に答える