(java) オブジェクトの初期化の順番

new した時点で、

親クラスのフィールド初期化

親クラスのコンストラクタ

子クラスのフィールド初期化

子クラスのコンストラクタ

の順で実行される。
例えば、以下のようなコードがあるとしよう。

Base.java

package hase.test;

public abstract class Base {
private String basestr = getStr();

public Base() {
System.out.println("constructor of base");
hoge();
}

abstract protected void hoge();

private String getStr() {
System.out.println("init Base property");
return "getStr";
}
}

Extends.java

package hase.test;

public class Extends extends Base {
private String exstr = getStr();

public Extends() {
super();
System.out.println("constructor of extends");
}

public void hoge() {
System.out.println("template method");
}

private String getStr() {
System.out.println("init extends property");
return "getStr";
}
}

test.java

package hase.test;

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
Extends base = null;
System.out.println("going to new");
base = new Extends();
}

}

これを実行すると、

going to new
init Base property
constructor of base
template method
init extends property
constructor of extends

となる。

これは要注意!
例えば、templateMethod で 子クラスのフィールド(exstr)に値を代入しても、子クラスのフィールドの宣言時に以下のように初期化すると・・・
private String str = null;
templateMethod より後にここが実行されてしまい、オブジェクト作った後にexstrはnullになってしまう。