ジュニアJava開発者向けのタスクとして提供されるコードがあります。私は5年間Javaを使用していますが、このコードは私を完全に混乱させます。
public class Main {
String variable;
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
}
public Main(){
printVariable();
}
protected void printVariable(){
variable = "variable is initialized in Main Class";
}
}
public class B extends Main {
String variable = null;
public B(){
System.out.println("variable value = " + variable);
}
protected void printVariable(){
variable = "variable is initialized in B Class";
}
}
出力は次のようになります。
Hello World!
variable value = null
しかし、に変更String variable = null;
すると、次のString variable;
ようになります。
Hello World!
variable value = variable is initialized in B Class
2番目の出力は私にとってより明確です。したがって、私が知る限り、Javaでの初期化のシーケンスは次のようになります。
- このルートの親クラスに到達すると、クラス階層のルート(Javaの場合は常にObjectクラス)に移動します。
- すべての静的データフィールドが初期化されます。
- すべての静的フィールド初期化子と静的初期化ブロックが実行されます。
- すべての非静的データフィールドが初期化されます。
- すべての非静的フィールド初期化子と非静的初期化ブロックが実行されます。
- デフォルトのコンストラクターが実行されます。
- 次に、基になる子クラスに対して手順を繰り返します。
this
また、スーパークラスのコンテキストでのキーワードの動作を説明する投稿があります-基本クラスのメソッドから基本クラスのオーバーライドされた関数を呼び出す
上記のルールに基づいて、次のようなシーケンスがあると想定します。
- クラスの新しいインスタンスを作成します
B
; - パーツクラスに移動し
Main
ます; main.variable
nullで初期化します。- 次に、クラスのデフォルトコンストラクタに移動します
Main
; - コンストラクターは
b.printVariable()
クラスのメソッドを呼び出しMain
ます; (なぜ呼ばないのmain.printvariable
ですか?this
ここにキーワードはありません。) - フィールド
b.variable
「変数はBクラスで初期化されます」 - 今、私たちはクラスに戻り
B
ます; - フィールド
b.variable
をnull値で初期化する必要があります、私は正しいですか?; B
実行されるクラスのデフォルトコンストラクタ
誰かがこの継承の初期化シーケンスがどのように機能するかについて完全かつ完全な説明をしてくれませんか。そして、なぜに変更String variable = null;
するString variable;
と別の出力につながるのですか。