まえがき
今日、Android ContentProvider の実装を眺めていて、新規プロセス時の Java クラスの静的フィールド、静的ブロック、非静的フィールド、非静的ブロック、コンストラクターの実行順序を突然思い出しました。実際、これは非常に古典的な質問であり、Java の基本知識の習得をテストします。面接ではこのような質問がたくさんあると思いますので、週末の時間を利用して復習してみてください。
結論
ここでは、最初にまとめた結論を示し、次に結論を検証するプログラムを作成します。 Java クラスが新しい場合、実行シーケンスは次のとおりです:
独自の静的属性と静的コード ブロックを実装します。 (コードが表示される順序に基づいて誰が最初に実行するかを決定します)
独自の非静的属性と非静的コード ブロックを実装します。
独自のコンストラクターを実行します。
継承されたクラスを新規に実装する過程での初期化実行シーケンスは次のとおりです:
親クラスのパブリック静的プロパティと静的ブロックレベルのコードを実装します。
独自の静的属性と静的ブロックレベルのコードを実装します。
親クラスの非静的プロパティと非静的コード ブロックを実装します。
親クラスのコンストラクターを実行します。
独自の非静的プロパティと非静的コード ブロックを実装します。
独自のコンストラクターを実行します。
ここで、静的コード ブロックと非静的コード ブロックについて簡単に紹介する必要があります。
1. 静的コード ブロック:
static {
}
2. 非静的コード ブロック
{
}
静的コード ブロックと非静的コード ブロックの類似点と相違点は次のとおりです。同じ点: どちらも J VM クラスのロード時およびコンストラクターの実行前に実行されます。一般に、一部の静的変数にはコード ブロック内で値が割り当てられます。
違い: 静的コード ブロックは非静的コード ブロックより前に実行されます (静的コード ブロック > 非静的コード ブロック)。静的コード ブロックは、初めて新規作成したときに 1 回だけ実行され、それ以降は実行されません。非静的コード ブロックは、新しいコード ブロックになるたびに実行されます。
検証 結論の最良の検証は、結果を証明するコードを書くことです。まず、継承なしでクラスを初期化するときの実行シーケンスを見てみましょう。 コードは次のとおりです。
public class InitOderTest { public static String STATIC_FIELD = "静态属性"; // 静态块 static { System.out.println(STATIC_FIELD); System.out.println("静态代码块"); } public String field = "非静态属性"; // 非静态块 { System.out.println(field); System.out.println("非静态代码块"); } public InitOderTest() { System.out.println("无参构造函数"); } public static void main(String[] args) { InitOderTest test = new InitOderTest(); } }
静的プロパティ
静的コードブロック
非静的プロパティ
非静的コードブロック
引数なしの構築 関数
次に、Java クラスが継承を実装するときに、実行順序が結論と一致するかどうかを検証してみましょう。テストコードは以下の通りです:
class ParentTest { public static String PARENT_STATIC_FIELD = "父类-静态属性"; // 父类-静态块 static { System.out.println(PARENT_STATIC_FIELD); System.out.println("父类-静态代码块"); } public static String parentField = "父类-非静态属性"; // 父类-非静态块 { System.out.println(parentField); System.out.println("父类-非静态代码块"); } public ParentTest() { System.out.println("父类—无参构造函数"); } } public class InitOderTest extends ParentTest { public static String STATIC_FIELD = "静态属性"; // 静态块 static { System.out.println(STATIC_FIELD); System.out.println("静态代码块"); } public String field = "非静态属性"; // 非静态块 { System.out.println(field); System.out.println("非静态代码块"); } public InitOderTest() { System.out.println("无参构造函数"); } public static void main(String[] args) { InitOderTest test = new InitOderTest(); } }
実行結果は以下の通りです:
親クラスの静的プロパティ
親クラスの静的コードブロック
静的プロパティ
静的コードブロック
親クラスの非静的プロパティ
親クラス - 非静的コード ブロック
親クラス - 引数なしのコンストラクター
非静的プロパティ
非静的コード ブロック
引数なしのコンストラクター
コード ブロックの実行順序のその他の例については、 Java の場合は、PHP 中国語 Web サイトの関連記事に注目してください。