2006-04-05 [長年日記]
■例外を吐くコンストラクタって
このプログラムは"null"が出力されるのか、"not null"が出力されるのか?直感的には"null"になりそうだが、out of order書き込みの可能性を考えると、一概にそうとは言えないかもしれない。
lethevert is a programmer - Java : コンストラクタで例外
経験的にはnullだ。
早速実験。
public class ExceptionalObject { public ExceptionalObject() { throw new RuntimeException(); } public int intValue() { return 5; } }
public class Object1 { public static void main(String[] args) { Object obj = null; try{ obj = new ExceptionalObject(); //例外発生 }catch(Exception e){} if (obj == null) { System.out.println("null"); }else{ System.out.println("not null"); } } }
結果は
null
次。
public class Object1 { public static void main(String[] args) { int i = 3; int j = 0; try{ j = (i++) + (new ExceptionalObject()).intValue(); }catch(Exception e){} System.out.println("i="+i); System.out.println("j="+j); } }
int の +演算子は左結合のはずだから、(i++)が先に評価される。
でも+演算子の右で例外発生。+演算子も=演算子も評価されないはず。
では(i++)はどうなるのか。これが(++i)なら4だろうと想像できるのだけど、さて?
結果。
i=4
j=0
i++によるインクリメントはちゃんと実行されている。
へー。そうなんだ……。
余談。
RuntimeExceptionではない例外を吐くコンストラクタ。
public class ExceptionalObject2 { public ExceptionalObject2() throws java.io.IOException { throw new java.io.IOException(); } }
うわ。気持ち悪い*1。
public class Object2 { ExceptionalObject2 obj = new ExceptionalObject2(); static ExceptionalObject2 staticobj = new ExceptionalObject2(); public Object2() { } }
とか書けません。
public class Object2 { ExceptionalObject2 obj = null; { try { obj = new ExceptionalObject2(); } catch (java.io.IOException e) {} } static ExceptionalObject2 staticobj = null; static { try { staticobj = new ExceptionalObject2(); } catch (java.io.IOException x) {} } public Object2() { } }
と書かざるをえない。ダサダサ。
というかコンストラクタでRuntimeExceptionじゃない例外を吐く様なものを、クラスやインスタンスの初期化で書くのがまずい。
そんなことになったら、どっか設計がおかしいと思って見直すべし、だなぁ。
追記
public class Object1 { public static void main(String[] args) { int i = 3; int j = 0; try{ j = (i++) + (new ExceptionalObject()).intValue(); }catch(Exception e){ System.out.println("i="+i); } System.out.println("i="+i); } }
ってどうなるんだ? と思った。
i=4
i=4
だった。catchに入る前に i++ によるインクリメントされてるってことか。
■Palm TX買った!
英語デバイス初めて!
J-OS初めて!
ネットワークでHotSyncしたいのにマシン名が出てこない!
Linuxマシンの名前は出てくるのに?
初めてづくしだ〜。
ハードリセットだ〜。あはは〜。
*1 極端な形で書いたから気持ち悪いのであって、コンストラクタがIOExceptionなどをthrowするのは、java.ioパッケージなどでは当たり前の話。