Javaのフィールドの初期化に奇妙な順序があることがわかったとき、私は非常に混乱しました。 init()の結果は、フィールドの初期化によって上書きされ 例コード:最初に使用する前にフィールドを初期化しないのはなぜですか?
public abstract class Parent {
public String parentField = "dupa";
public Parent(){
init(); // uhh, bad practice to call abstract method in a super constructor
}
protected abstract void init();
}
public class Child extends Parent {
public String childField = null; // assigning null is unnecessary, another bad practice
@Override
protected void init(){
childField = "initialized";
System.out.println("After init(): " + childField);
}
}
...
Child child = new Child(); // OUTPUT: After init(): initialized
System.out.println("After all: " + child.childField); // OUTPUT: After all: null
私はnew Child();
を呼び出すときに実行順序が何であるかが分かった:
- 親フィールドの初期化が、childFieldがすでに存在し、デフォルトを持っています親コンストラクタによって呼び出された値(childField = NULL)
- 親コンストラクタ
- オーバーライドのinit()(CH私はこの例では、悪い習慣に満ちている知っているchildField =ヌル(再び)
- 子コンストラクタ
:ildField =
このような初期化の目的は何ですか? フィールドイニシャライザが最初に使用される前に実行されないのはなぜですか? フィールドがまだ初期化されていない場合は、なぜそれを使用することができますか?
'ChildField'の初期化は、' Parent'のためのctorが終了した後どのように 'Child' _ _において起こりますか? –
コンストラクタでオーバーライド可能なメソッドを呼び出す理由は、不完全なオブジェクトが他のコードに漏れることです。同様に、子フィールド初期化子は、 'super'が完全に構築されることを期待しています。 – 4castle
子と親の両方にparamsを持つコンストラクタを使用すると、子コンストラクタが独自のコンストラクタコードの前に親を呼び出すように強制されます。この種の質問は私にはボットが生成されたようだ – efekctive