こんにちは、ともです。
今回はcatch句で例外が発生した際の処理の書き方について書きます。
catch句の中で例外が発生し、その例外をそのままthrowしてしまうとtry句で発生した例外が闇に葬られてしまいますよね。
その場合の書き方について記事を書きます。結論としてはaddSuppressedしよう。
ThrowableクラスのaddSuppressedを確認していただければ詳細分かります。
catch句で例外を投げる状況
package blog1;
/**
* try句の例外が消えてしまうサンプル
* @author tomo
*/
public class Test {
/**
* 例外をcatchしStackTraceを表示するメソッド
* @param args
*/
public static void main(String[] args) {
try {
doMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* catch句で例外をthrowするメソッド
* @throws Exception
*/
private static void doMethod() throws Exception {
try {
throw new Exception("throw in try");
} catch(Exception e) {
throw new Exception("throw in catch");
}
}
}
doMethodのtry句で例外が発生しています。
しかし、catch句でも例外が発生してしまいました。
この場合mainメソッドでcatchする例外はcatch句で発生した例外になります。
よって、printStackTraceの値はjava.lang.Exception: throw in catch
となります。つまりtry句で発生した例外原因が消えてしまいました。
これでは本当の原因例外が分かりませんね。
addSuppressed使おう
addSuppressedで原因例外を残しましょう。
suppressed(抑圧された)という意味です。つまりtry句の例外は抑圧されてしまった訳です。その抑圧された例外を追加するメソッドがaddSuppressedです。
下記のようなコードを書きました。
package blog1;
/**
* try句の例外が消えてしまうサンプル
* @author tomo
*/
public class Test {
/**
* 例外をcatchしStackTraceを表示するメソッド
* @param args
*/
public static void main(String[] args) {
try {
doMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* catch句で例外をthrowするメソッド
* @throws Exception
*/
private static void doMethod() throws Exception {
try {
throw new Exception("throw in try");
} catch(Exception expInTry) {
Exception expInCatch = new Exception("throw in catch");
expInCatch.addSuppressed(expInTry);
throw expInCatch;
}
}
}
addSupprssedメソッドでtry句内で発生した、抑圧されてしまう例外を追加してあげます。追加後に例外をthrowします。
そうすると下記のようなprintStackTraceとなります。
java.lang.Exception: throw in catch
at Blog/blog1.Test.doMethod(Test.java:28)
at Blog/blog1.Test.main(Test.java:15)
Suppressed: java.lang.Exception: throw in try
at Blog/blog1.Test.doMethod(Test.java:26)
... 1 more
原因例外も残っていますね。これで問題箇所の特定が可能になります。
めでたし、めでたし。