78

次のプログラムの出力を説明できる人はいますか? コンストラクターはインスタンス変数の前に初期化されると思いました。したがって、出力が「XZYY」になると予想していました。

class X {
    Y b = new Y();

    X() {
        System.out.print("X");
    }
}

class Y {
    Y() {
        System.out.print("Y");
    }
}

public class Z extends X {
    Y y = new Y();

    Z() {
        System.out.print("Z");
    }

    public static void main(String[] args) {
        new Z();
    }
}
4

5 に答える 5

123

初期化の正しい順序は次のとおりです。

  1. クラスが以前に初期化されていない場合、静的変数初期化子と静的初期化ブロック (テキスト順)。
  2. コンストラクターでの super() 呼び出し (明示的または暗黙的)。
  3. インスタンス変数初期化子とインスタンス初期化ブロック (テキスト順)。
  4. super() の後のコンストラクターの残りの本体。

Java 仮想マシン仕様のセクション2.17.5-6 を参照してください。

于 2013-02-11T05:21:49.663 に答える
69

クラスファイルの逆コンパイルされたバージョンを見ると

class X {
    Y b;

    X() {
        b = new Y();
        System.out.print("X");
    }
}

class Y {
    Y() {
        System.out.print("Y");
    }
}

public class Z extends X {

    Y y;

    Z() {
        y = new Y();
        System.out.print("Z");
    }

    public static void main(String args[]) {
        new Z();
    }
}

yコンストラクタ内でインスタンス変数が移動していることがわかるので、実行シーケンスは次のようになります。

  1. のコンストラクターを呼び出しますZ
  2. のデフォルトコンストラクターをトリガーしますX
  3. Xコンストラクタの最初の行new Y()が呼び出されます。
  4. Y を印刷
  5. X を印刷
  6. コンストラクター Z の最初の行を呼び出すnew Y()
  7. 印刷するY
  8. Z を印刷

すべてのインスタンス変数は、コンストラクター ステートメントを使用して初期化されます。

于 2013-02-11T03:47:10.107 に答える
-6

初期化シーケンスは JLS 12.5 で指定されています。

1.まず、新しいオブジェクトにメモリが割り当てられます

2.次に、オブジェクト内のすべてのインスタンス変数 (このクラスとそのすべてのスーパークラスで定義されたものを含む) がデフォルト値に初期化されます。

3.最後に、コンストラクターが呼び出されます。

https://stackoverflow.com/questions/26552799/which-run-first-default-values-for-instance-variables-or-super-constructors

于 2016-01-11T09:28:23.630 に答える