1

私はJava Certification Bates and Sierraの本から勉強してきましたが、第2章のコンストラクターの説明に困惑しています:

public class Animal {
    String name;

    Animal(String name) {
        super();

        {System.out.println("Hello");} //I put this in myself

        this.name = name;
    }

    Animal() {
        this(makeRandomName());
    }


    static String makeRandomName() {
        int x = (int) (Math.random() * 5);
        String name = new String[] {"Fluffy", "Fido",
        "Rover", "Spike",
        "Gigi"}[x];
        return name;
    }

    public static void main (String [] args) {
        Animal a = new Animal();
        System.out.println(a.name);
        Animal b = new Animal("Zeus");
        System.out.println(b.name);
    }
}

以下は、ベイツとシエラの本からのものです。

makeRandomName() メソッドが static とマークされていることに注意してください。これは、スーパー コンストラクターが実行されるまで、インスタンス (つまり、非静的) メソッドを呼び出す (またはインスタンス変数にアクセスする) ことができないためです。また、スーパー コンストラクターは、7 行目のコンストラクターからではなく、3 行目のコンストラクターから呼び出されるため、8 行目では静的メソッドのみを使用して名前を生成できます。

私は実験を行い、オーバーロードされたコンストラクターにスーパー呼び出しを挿入しました。結果は次のとおりです。

 Hello 
 Rover
 Hello
 Zeus

これらの結果から、Hello が Zeus と Rover の前に出力されるため、オーバーロードされたコンストラクターとスーパー コンストラクターが静的メソッドの前に実行されているように見えます。では、なぜ静的変数が必要なのでしょうか?

私は何が欠けていますか?

4

3 に答える 3

3

メソッドmakeRandomName()はの前に呼び出されsuperます。print ステートメントは、他のコンストラクターの実行後に生成された値を消費していることを示しているだけです。違いを確認するには、print ステートメントを に直接挿入しますmakeRandomName()

于 2013-10-03T01:32:14.947 に答える
1

コンストラクターでのsuper()呼び出しは何も変更しません。とにかく、コンパイラによって暗黙的に追加されたはずです。

実行に関しては

Animal a = new Animal();

空のコンストラクターを呼び出します。

this(makeRandomName());

makeRandomName()Stringが実行され、 aを受け入れる 1 引数のコンストラクターを呼び出すために使用されるa を返しますString"Hello"が出力され、フィールドnameが割り当てられます。コンストラクターが戻ります。ランダムな名前が出力されます。

次に、1引数のコンストラクターが呼び出されます

Animal b = new Animal("Zeus");

を出力"Hello"し、フィールドを設定して、戻ります。次に、mainプリント"Zeus"


では、なぜ静的変数が必要なのでしょうか?

メソッドから削除staticしたmakeRandomName()場合、以下はコンパイルされません

Main() {
    this(makeRandomName());
}

オブジェクトはまだ初期化されていないため、メソッドを呼び出すことはできません。

于 2013-10-03T01:34:26.980 に答える