インスタンス変数の初期化タイミングとか
例えばClassAをこんな風に定義。
public class ClassA {public String a = null;
public ClassA() {
super();
initialize();
}public void initialize() {
a = "a";
}
}
当然なんだけど、いちおうコレを確認すると
ClassA a = new ClassA();
System.out.println(a.a);
出力はこんな感じ。
aまあ当然。
んじゃあ、これを継承して、initialize()をoverrideしてこんな感じに。
public class ClassB extends ClassA {
String b = null;public ClassB() {
super();
}
@Override
public void initialize() {
b = "b";
}
}
同じようにこんな感じで確認すると。
ClassB b = new ClassB();
System.out.println(b.a);
System.out.println(b.b);
予想としては、aが初期化されないのでnull, bが"b"って思ったんだけど、結果は...
null
null
あまりにも腑に落ちないのでデバッグで追って見ると、動作としてはClassB()
からClassA()
、ここまではいい。その時点でa = null;
されて、そこからinitialize()
、overrideしてるからここではClassB
のinitialize()
が呼ばれて、b = "b";
。その後、ClassB()
のsuper()
に戻ってきてb = null
される。つまりString b = null;
のb = null
先にinitialize()
のb = "b";
が動いてるって事らしい。
ははぁーん、なるほど。"インスタンス初期化子"ってのは、こんな時に使うわけか。と、妙に納得。
インスタンス初期化子とは : JavaA2Z
クラス内に、何も修飾せず「{ 実装 }」と記述することで、コンストラクタが呼び出される前にメソッドとして呼び出される。
こんな感じにすればいいってことか。
public class ClassB extends ClassA {String b;
{
b = null;
}public ClassB() {
super();
}@Override
public void initialize() {
b = "b";
}
}
結果。
null
null
...あれ...?
変わってないし...
だれか納得行く答えをください...