発生した例外を処理する方法は、throwsを使って呼び出し元のメソッドに処理を投げる方法と、もう1つ方法があります。それが「try catch文」を使って例外を受け取り、処理する方法です。
try catch文では、「try {処理}」で例外が起きる可能性のある処理を囲い、「catch(例外) {処理}」で、指定した例外クラスに対応した処理を行います。
この時、例外は「例外の型 変数」と書き、この変数は例外の詳細情報を得たり、出力に利用したりできます。
try { 例外がthrowされる可能性のある処理 「throw new Exception系クラス()」 があるか 「throws Exception系クラス」の付いたメソッドがある } catch (例外の型 変数) { 例外が起きた時の処理 }
catchブロックは、例外の種類に合わせて複数書くことができます。
try { method(); // throws ExceptionA, ExceptionB } catch (ExceptionA eA) { 例外Aが起きた時の処理 } catch (ExceptionB eB) { 例外Bが起きた時の処理 }
注意すべき点は、catchの丸括弧に指定した例外をAとすると、Aの型の子孫は全てcatchされてしまうことです。
たとえば、ExceptionAを継承したExceptionBがあるとします。catchの丸括弧にExceptionAを指定すると、ExceptionAだけでなく、ExceptionBもキャッチされていしまいます。
そのため例外クラスの共通の祖先であるExceptionを丸括弧に書いてしまうと、その他の全ての例外処理がキャッチされてしまい、その後のcatchブロックには処理がいかなくなります。
例外を受け取る際は、例外クラスの継承関係に注意する必要があります。
try { method(); // throws ExceptionA, ExceptionB } catch (Exception e) { 全ての例外がここで処理されてしまう } catch (ExceptionB eB) { ここには処理が来ることはない }
受け取った例外は、「printStackTrace」メソッドで例外情報を出力することが多いです。
package sample;
public class Sample {
public static void main(String[] args) {
try {
MethodA();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void MethodA() throws Exception {
throw new Exception();
}
}
java.lang.Exception at sample.Sample.MethodA(Sample.java:13) at sample.Sample.main(Sample.java:6)
この出力結果は、例外の種類がまず書かれ、その後に原因のメソッドと、発生したファイル名と行番号が出力されます。このメソッドの情報は、呼び出しメソッドがある場合、再帰的に呼び出し元をたどり、全ての情報を表示します。
printStackTraceの情報は、デバッグに非常に有用なので活用するとよいでしょう。
try catch文は、その末尾に「finaly」ブロックが付く場合があります。このfinalyブロックには、例外が発生した場合も、発生しなかった場合も、処理されるコードを書きます。
処理が終わった場合に、ファイルを閉じたり、ネットの接続を切ったり、そういった使い方をします。
try {
例外がthrowされる可能性のある処理
} catch (受け取るException系クラス 変数) {
例外が起きた時の処理
} finaly {
例外が起きた場合も起きなかった場合も
最終的にここを通る
}