Java初期化順序の検証(スーパータイプコンストラクターが呼び出される前にXXXを参照できないことによってトリガーされた思考)



Verification Java Initialization Order



1.問題の発見

最近データベースでコーディングしているときに、「スーパータイプコンストラクターが呼び出される前にXXXを参照できません」というエラーメッセージを誤って見つけました。意味は明らかです。この変数は、親クラスのコンストラクターが初期化される前に参照することはできません。開始修飾子がこの変数に追加された場合、エラーは報告されません。
画像

2.推測の検証

では、静的な変更を追加した後、なぜエラーの報告を停止するのですか?明らかに、これはJavaの初期化順序に関連しています。したがって、Coderは、Javaの初期化の順序を検証するための検証コードを作成しました。



/** * father */ public class Base { static String sVar = getString('Parent class static variable initialization') public String var = getString('Parent class non-static variable initialization') static { System.out.println('The static initialization block of the parent class') } { System.out.println('Non-static initialization block of parent class') } public Base() { System.out.println('Parent class constructor start') draw('The parent class calls the draw method')//The method covered by the subclass will be called, here is null System.out.println('Parent class constructor end') } static String getString(String base) { System.out.println(base) return base } public void draw(String string) { System.out.println(string) } } /** * Subclass */ public class SubClass extends Base { public String var = getString('Subclass initializes non-static variables') private String subVar = getString('Subclass initializes private variables') static String superVar = getString('Subclass initializes static variables') static { System.out.println('Static initialization block for subclasses') } { System.out.println('Non-static initialization block for subclasses') } SubClass() { System.out.println('Subclass constructor start') draw('Subclass calls draw method') System.out.println('Subclass constructor end') } public void draw(String string) { System.out.println(string + subVar) } public static void main(String[] args) { new SubClass() } } Parent class static variable initialization Static initialization block of the parent class Subclass initializes static variables Static initialization block of subclass Parent class non-static variable initialization Non-static initialization block of the parent class Parent class constructor start The parent class calls the draw method null Parent class constructor end Subclass initializes non-static variables Subclass initializes private variables Non-static initialization block of subclass Subclass constructor start The subclass calls the draw method and the subclass initializes private variables Subclass constructor end

3.結果分析

この結果から、記事の冒頭でエラーの理由を明確に確認できます。親クラスコンストラクターの初期化は、サブクラスの非静的変数の初期化よりも早く、サブクラスの静的変数の初期化よりも遅いです。 。したがって、変数を静的変更に変更しても、エラーは報告されません。 Java初期化プロセスを自分で試すことができます。これは、将来のプログラミングで非常に役立ちます。