問題です。以下で示すプログラムを実行すると、どうなるでしょう?
package case1; public class Test { public static void main(String[] args) throws Exception { method(); System.out.println("mainの最後"); } public static void method() throws Exception { try { throw new Exception(); } finally { } } }
答えは例外が発生し、コンソールにはスタックトレースが表示されます。
・・・まあ、当たり前ですね。
では次の場合は?
package case1; public class Test { public static void main(String[] args) throws Exception { method(); System.out.println("mainの最後"); } public static void method() throws Exception { try { throw new Exception(); } finally { return; } } }
先ほどのソースとの違いは、こちらはfinally句でreturnしています。
今日の教訓その1
finally句でreturnすると、try句やcatch句で投げられた例外が亜空間へすっ飛ぶ。
それぞれの実装は次の通りです。
package case2; public class One { public static int value = 1; }
package case2; public class Test { private final int value; private static final Test TWO = new Test(); private static final int ONE = One.value; public Test() { value = ONE + ONE; } public static void main(String[] args) throws Exception { System.out.println(TWO.value); } }
1+1 を、ちょっとまどろっこしくやっているだけです。
当然、実行すると2と表示・・・
されない!?
今日の教訓その2
1+1=0です。
・・・いえ、わたくし嘘をつきました。
タネを明かすと、こうすれば2になります。
package case2; public class Test { private final int value; private static final int ONE = One.value; private static final Test TWO = new Test(); public Test() { value = ONE + ONE; } public static void main(String[] args) throws Exception { System.out.println(TWO.value); } }
ポイントは、5行目と6行目を入れ替えたところです。
今日の教訓その3
1+1=2である。
staticなフィールド変数は上から順に初期値が設定される。
本当のタネ明かし
なぜ突然「Java言語クイズ」なんて言い出したかというと、面白いサイトを発見したからです。
JPCERT/CC > セキュアコーディング > Java セキュアコーディングスタンダード CERT/Oracle版
ここには、Java言語にてプログラミングを行う際に、セキュアプログラミングの観点から気を付けないといけないことについて列挙されています。列挙されている項目それぞれについて「やって駄目な例」と「こうすべき例」が載っており、解説も非常にわかり易く、Java技術者必見の内容と言えます。今回のネタはこのサイトから仕入れました。
昔読んだEffective Javaに載っていた事のような気もしましたが、都合のいい事に(?)もうすっかり忘れていたので、非常に勉強になりました。
C言語版もあるようです。
→CERT C セキュアコーディングスタンダード
本にもなっているようです。