導入
Java開発において、堅牢なアプリケーションを作るために「例外処理」は避けて通れません。しかし、ただ闇雲にtry-catchを記述するだけでは、予期せぬ不具合や保守性の低下を招きます。本稿では、Javaの例外階層の頂点であるjava.lang.Throwableを理解し、現場で推奨されるモダンな例外ハンドリングの手法を解説します。
基礎知識
java.lang.Throwableは、Javaにおけるすべてのエラーや例外の親クラスです。大きく分けて以下の2つのサブクラスが存在します。
1. Error: JVMのメモリ不足やスタックオーバーフローなど、プログラム側では回復不可能な深刻な事態を表します。これらは原則としてcatchすべきではありません。
2. Exception: プログラムで制御可能な問題です。さらに、コンパイル時にチェックが強制される「チェック例外」と、実行時に発生する「非チェック例外(RuntimeException)」に分かれます。
実装/解決策
現場では以下の手法を組み合わせることで、コードの可読性と安全性を高めます。
- Multi-catch: Java 7以降、複数の例外を一つのcatchブロックで処理可能です。冗長なコードを削減できます。
- try-with-resources: Closeableインターフェースを実装したリソース(ファイルやDB接続など)を、自動的にクローズする仕組みです。finallyブロックでの明示的なcloseが不要となり、メモリリークのリスクを大幅に減らせます。
サンプルプログラム
以下のコードは、ファイル読み込みを例にMulti-catchとtry-with-resourcesを組み合わせた実用的な実装です。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
public class ExceptionHandlingSample {
public static void main(String[] args) {
String filePath = "data.txt";
// try-with-resources: 処理終了後に自動でBufferedReaderをクローズします
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
System.out.println(reader.readLine());
} catch (NoSuchFileException e) {
// 特定の例外を個別ハンドリング
System.err.println("ファイルが見つかりません: " + e.getMessage());
} catch (IOException | SecurityException e) {
// Multi-catch: 関連する複数の例外をまとめて処理
System.err.println("入出力エラーまたは権限エラーが発生しました: " + e.getMessage());
}
}
}
応用・注意点
例外処理を行う際、以下の点に注意してください。
- 例外を握りつぶさない: catchブロック内で何もしない(空のままにする)のはNGです。ログを出力するか、適切な例外でラップして再スロー(Exception Chaining)しましょう。
- 広すぎるcatchは避ける: Exceptionクラスを直接catchすると、想定外のRuntimeExceptionまでキャッチしてしまい、バグの発見を遅らせる原因になります。可能な限り具体的な例外クラスをキャッチしてください。
- Throwableをキャッチしない: Errorまでキャッチしてしまうと、JVMの異常終了を妨げたり、デバッグが極めて困難になります。必ずException以下をキャッチするようにしましょう。
これらを意識するだけで、あなたの書くコードの品質は一段と向上するはずです。ぜひ日々の開発に取り入れてみてください。

コメント