Javaクラスの初期化順序

継承なしの場合:

1. 実行順序

  1. 静的メンバ変数
  2. 静的コードブロック
  3. 通常のメンバ変数
  4. 通常のコードブロック
  5. コンストラクタ

2. 要約:

  • 静的 -> 通常
  • 変数 -> コードブロック -> コンストラクタ
  • コンストラクタは最後に実行される

3. サンプルコード:

public class Parent {
  private static String name = "zct";
  private int age = 50;

  {
    System.out.println("parent age: " + age);
    System.out.println("parent 通常のコードブロック");
  }

  static {
    System.out.println("parent static name: " + name);
    System.out.println("parent 静的コードブロック");
  }

  public Parent() {
    System.out.println("parent コンストラクタ");
  }
}

4. テスト:

@org.junit.Test
public void test() {
  Parent parent = new Parent();
}

5. テスト結果:

parent static name: zct
parent 靜的コードブロック
parent age: 50
parent 通常のコードブロック
parent コンストラクタ

子クラスが親クラスを継承する場合:

1. 実行順序

  1. 親クラスの静的メンバ変数
  2. 親クラスの静的コードブロック
  3. 子クラスの静的メンバ変数
  4. 子クラスの静的コードブロック
  5. 親クラスのメンバ変数
  6. 親クラスのコードブロック
  7. 親クラスのコンストラクタ
  8. 子クラスのメンバ変数
  9. 子クラスのコードブロック
  10. 子クラスのコンストラクタ

2. 要約:

  • まず親クラス、次に子クラス
  • 子クラスに静的メンバ変数と静的コードブロックがある場合、親クラスの静的メンバ変数と静的コードブロック後に子クラスの静的メンバ変数と静的コードブロックが実行される。
  • 子クラスの静的メンバ変数と静的コードブロックは、親クラスの通常のメンバ変数、コードブロック、およびコンストラクタよりも先に実行される。
  • 静的 -> 通常の順序

3. サンプルコード:

public class Child extends Parent {
  private static String name = "zlc";
  private int age = 26;

  {
    System.out.println("child age: " + age);
    System.out.println("child 通常のコードブロック");
  }

  static {
    System.out.println("child static name: " + name);
    System.out.println("child 静的コードブロック");
  }

  public Child() {
    System.out.println("child コンストラクタ");
  }
}

4. テスト:

@org.junit.Test
public void test() {
  Child child = new Child();
}

5. テスト結果:

parent static name: zct
parent 静的コードブロック
child static name: zlc
child 静的コードブロック
parent age: 50
parent 通常のコードブロック
parent コンストラクタ
child age: 26
child 通常のコードブロック
child コンストラクタ

タグ: Java クラス初期化 継承 JUnit

6月19日 16:12 投稿