これは実際、昨年学校の採用活動中に私が遭遇した Alibaba の筆記試験の問題です (少し古いことは認めますが、私の記憶が正しければ、これは Java に関するオプションの主要な質問でした)。もちろん、質問の意味はそれほど単純ではありません。プログラムの実行後にすべての System.out.println の出力結果を書き込むだけです。プログラムは質問によって与えられ、実行順序は異なります。各 System.out.println は最終的なプログラム出力につながります。結果も異なります。
具体的な質問は絶対に思い出せませんが、クラス A に静的変数、静的ステートメント ブロック、非静的変数、非静的ステートメント ブロック、コンストラクター、静的メソッドがある場合は、質問を直接変更できます。クラスB、非静的メソッド。同時に、クラスAはクラスBを継承します。Aをインスタンス化するとき、クラス内のロード順序はどうなるのでしょうか?
その後、私は自分で小さなデモを書きました。 、そしてクラスを理解しました 実際の内部読み込みはスムーズで、テストコードは次のとおりです:
Class B:
public class B{ //静态变量 static int i=1; //静态语句块 static { System.out.println("Class B1:static blocks"+i); } //非静态变量 int j=1; //静态语句块 static{ i++; System.out.println("Class B2:static blocks"+i); } //构造函数 public B(){ i++; j++; System.out.println("constructor B: "+"i="+i+",j="+j); } //非静态语句块 { i++; j++; System.out.println("Class B:common blocks"+"i="+i+",j="+j); } //非静态方法 public void bDisplay(){ i++; System.out.println("Class B:static void bDisplay(): "+"i="+i+",j="+j); return ; } //静态方法 public static void bTest(){ i++; System.out.println("Class B:static void bTest(): "+"i="+i); return ; } }
Class A:
public class A extends B{ //静态变量 static int i=1; //静态语句块 static { System.out.println("Class A1:static blocks"+i); } //非静态变量 int j=1; //静态语句块 static{ i++; System.out.println("Class A2:static blocks"+i); } //构造函数 public A(){ super(); i++; j++; System.out.println("constructor A: "+"i="+i+",j="+j); } //非静态语句块 { i++; j++; System.out.println("Class A:common blocks"+"i="+i+",j="+j); } //非静态方法 public void aDisplay(){ i++; System.out.println("Class A:static void aDisplay(): "+"i="+i+",j="+j); return ; } //静态方法 public static void aTest(){ i++; System.out.println("Class A:static void aTest(): "+"i="+i); return ; } }
Class ClassLoading:
public class ClassLoading { public static void main (String args[]) { A a=new A(); a.aDisplay(); } }
プログラムの実行結果は次のとおりです。図:
上の図を通して、Java クラスの読み込みプロセス全体をより明確に見ることができます。
1.クラスAをロードしたい場合は、まずその親クラスB(Object)の静的変数と静的ステートメントブロックをロードして実行します(実行順序は配置順です)。
2. 次に、実行クラス A の静的変数と静的ステートメント ブロックをロードします。 (ステップ 1 と 2 は 1 回だけ実行されます)
3. クラス A をインスタンス化する必要がある場合は、まずその親クラス B のコンストラクターを呼び出し、その親クラス B のコンストラクターを呼び出す前に、最初に親クラスを呼び出します。 -B の静的変数と非静的ステートメント ブロック。最後に、親クラス B のコンストラクターを呼び出して初期化します。
4. 次に、クラス A の非静的変数と非静的ステートメント ブロックを順番に呼び出します。最後に、初期化のために A のコンストラクターを呼び出します。 (ステップ 3 と 4 を繰り返すことができます)
5. 静的メソッドと非静的メソッドはどちらも受動的呼び出しです。つまり、システムが自動的に呼び出して実行することはないため、ユーザーが呼び出していないときは実行されません。主な違いは、静的メソッドはクラス名を使用して直接呼び出すことができるのに対し (オブジェクトをインスタンス化することもできます)、非静的メソッドはオブジェクトがインスタンス化された後にのみ呼び出すことができることです。
今日はここまでです。何か良くない点や間違っている点がありましたら、ご指摘ください。修正させていただきます。ありがとうございます。
Java のクラスのロード順分析 (面接の質問でよく使用される) に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。