(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になってしまう。