97

親と子の2つのクラスがあります

public class Parent {    
    public Parent() {
        System.out.println("Parent Constructor");
    }    
    static {
        System.out.println("Parent static block");    
    }    
    {
        System.out.println("Parent initialisation  block");
    }
}

public class Child extends Parent {    
    {
        System.out.println("Child initialisation block");
    }
    static {
        System.out.println("Child static block");
    }

    public Child() {
        System.out.println("Child Constructor");
    }    
    public static void main(String[] args) {
        new Child();    
    }
}

上記のコードの出力は次のようになります。

Parent static block
Child static block
Parent initialization  block
Parent Constructor
Child initialization block
Child Constructor

Java がその順序でコードを実行するのはなぜですか? 実行順序を決定するルールは何ですか?

4

11 に答える 11

69

私は視覚的に学習するので、 SSCCEとして順序を視覚的に表したものを次に示します。

public class Example {

    static {
        step(1);
    }

    public static int step_2 = step(2);
    public int step_8 = step(8);

    public Example(int unused) {
        super();
        step(10);
    }

    {
        step(9);
    }

    // Just for demonstration purposes:
    public static int step(int step) {
        System.out.println("Step " + step);
        return step;
    }
}
public class ExampleSubclass extends Example {

    {
        step(11);
    }

    public static int step_3 = step(3);
    public int step_12 = step(12);

    static {
        step(4);
    }

    public ExampleSubclass(int unused) {
        super(step(7));
        step(13);
    }

    public static void main(String[] args) {
        step(5);
        new ExampleSubclass(step(6));
        step(14);
    }
}

これは以下を出力します:

Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
Step 13
Step 14

staticパーツの順序が重要であることに注意してください。Examplestaticものとのものの順序の違いを振り返ってくださいExampleSubclass

また、インスタンス初期化ブロックは、順序に関係なく、コンストラクターでの呼び出しの直後に常に実行されることに注意してくださいsuper()(その呼び出しが暗黙的/省略されている場合でも)。ただし、初期化ブロックとフィールド初期化子の間では順序が重要です。

于 2016-01-25T20:08:23.887 に答える
60

遊びにはいくつかのルールがあります

  • 静的ブロックは常にオブジェクトが作成される前に実行されるため、親と子の両方の静的ブロックから出力メッセージが表示されるのはそのためです。
  • 現在、サブクラス(子)のコンストラクターを呼び出すと、このコンストラクターは、super();独自のコンストラクターを実行する前に暗黙的に呼び出します。初期化ブロックはコンストラクター呼び出しの前でも機能するため、最初に呼び出されます。これで、親が作成され、プログラムは同じプロセスを経る子クラスを作成し続けることができます。

説明:

  1. 親の静的ブロックが最初にロードされ、クラスがロードされるときに静的ブロックが呼び出されるため、最初に実行されます。
于 2013-10-24T08:59:39.523 に答える
9
  • 静的 init ブロックは、クラスのロード時に実行されます。
  • クラス階層では、静的 init ブロックの実行順序は最上位クラスから開始されます。
  • クラスでは、静的ブロックの実行順序は上から下です。
  • 上記のルールは、静的ブロックがクラス内のどこにあるかに関係なく適用されます。

(コードでは、親の静的ブロックが最初に実行され、次に子クラスの静的ブロックが実行されます。)

  • インスタンスの初期化ブロックは、super(); の呼び出し後に実行されます。コンストラクターで。
    • 常に super(); は、デフォルト コンストラクターの最初のステートメントです。

Child オブジェクトを作成するときのコード内:

  • Child クラスのデフォルトのコンストラクターが実行されます。
  • super(); を呼び出します。コンストラクタ。
  • 次に、スーパークラスのコンストラクターが実行されます。
  • Parent クラスはその super(); を実行します。電話。
  • その後、Parent クラスのインスタンスの初期化ブロックが実行されます (上から下へ)。
  • 次に、コンストラクター内のコードが実行されます (存在する場合)。
  • その後、Child クラスに戻り、Child クラス インスタンスの初期化ブロックを実行します。
  • 最後に、子コンストラクターのコードが実行されます (存在する場合)。
于 2018-06-21T10:29:38.353 に答える
5

Java の static ブロックは main メソッドの前に実行されます。Java クラスで Static ブロックを宣言すると、クラスのロード時に実行されます。これは静的変数で初期化されます。主に JDBC で使用されます。Java の静的ブロックは、クラスがロードされるたびに実行されます。これは、静的初期化ブロックとも呼ばれます。Java の静的ブロックは、クラスがメモリにロードされるときに初期化されます。これは、JVM がバイト コードを読み取るときを意味します。初期化は何でもかまいません。変数の初期化またはそのクラスのすべてのオブジェクトで共有する必要があるその他のものにすることができます。静的ブロックは、中かっこ { } で囲まれた通常のコード ブロックであり、静的キーワードが前に付いています。

そのため、静的ブロックが最初に実行されました。

インスタンス初期化ブロック: クラスのインスタンスが作成されるたびに実行されます。

そのため、次の初期化ブロックは、クラスのインスタンスが作成されるときに実行されます。

次に、コンストラクターが実行されました

于 2013-10-24T09:05:22.930 に答える
3

ステップ バイ ステップ デバッガーを使用してオブジェクトの構築プロセスをチェックアウトし、オブジェクトがフェーズをどのように通過しているかを確認できるビューを用意すると、非常に役立ちます。これは、より高い視点からの視点を明確にするのに非常に役立つことがわかりました。Eclipse は、関数へのデバッガーのステップを使用してこれを支援できます。

于 2015-12-10T10:14:56.303 に答える
1

クラスが JVM にロードされると、静的ブロックが実行されます。initブロックは、オブジェクトが作成されるコンストラクタにコピーされ、オブジェクトの作成前に実行されます。

于 2015-07-16T19:24:13.630 に答える