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パッケージなどでは当たり前の話。
