Javaの開発現場では、エラーハンドリングの品質がソフトウェアの安定性と保守性を大きく左右します。しかし、try-catch文を安易に使ってしまうことで、本来気づくべきバグを隠してしまうことがあります。本記事では、Javaでcatchしてはいけない例外(Exception)を7つ厳選し、それぞれの理由と正しい対処法を詳しく解説します。
Javaの例外の基本構造
まず、Javaの例外構造を理解しておきましょう。
Throwable
├── Error(catchすべきでない)
└── Exception
└── RuntimeException(catchが任意)
今回注目するのは、Exception
の中でもcatchするのが任意な RuntimeException
を継承するクラスたちです。これらの例外は「開発者のミス」を示すことが多く、catchすべきではないものが含まれています。
catchしてはいけない例外7選
1. NullPointerException
理由:
null参照によるアクセスエラー。事前のnullチェックで防ぐべきもので、catchしても問題の根本は解決しません。
悪い例:
try {
obj.doSomething();
} catch (NullPointerException e) {
// とりあえず無視
}
正しい対応:
if (obj != null) {
obj.doSomething();
}
2. IndexOutOfBoundsException
理由:
配列やリストに対する無効なインデックスアクセス。ロジックミスであるためcatchで握りつぶすべきではありません。
正しい対応:
- リストのサイズを事前にチェックする
- 安全なアクセスを設計する
3. IllegalArgumentException
理由:
メソッドに不正な引数が渡されたことを示します。呼び出し側の設計ミスであるため、catchで処理すべきではありません。
対処:
- 呼び出し側で引数チェックを行う
- APIの仕様を正しく理解する
4. IllegalStateException
理由:
オブジェクトの状態が不適切なときにメソッドが呼び出されたことを示す例外。catchして処理するより、状態管理の見直しが必要です。
5. ClassCastException
理由:
不適切な型キャストによって発生。設計段階で型安全性を確保すべきであり、catchしても安全な処理はできません。
対処:
- instanceof チェックの活用
- ジェネリクスの適切な使用
6. UnsupportedOperationException
理由:
操作がサポートされていない場合に発生。例えば、List.of()
で作成した不変リストに add()
を実行するなど。catchではなく仕様理解が大切。
7. NumberFormatException
理由:
文字列を数値に変換する際に失敗したときに発生。ユーザー入力に対する事前バリデーションで防ぐべきです。
正しい対応:
if (input.matches("\\d+")) {
int number = Integer.parseInt(input);
}
catchしてはいけない理由とは?
これらの例外の多くは、「発生すること自体がバグ」です。catchして握りつぶしてしまうと、以下のリスクがあります。
- 根本原因の特定が困難になる
- 隠れたバグが本番で顕在化する
- エラーをログにも残さず、障害対応が遅れる
エラーハンドリングの目的は「異常に気づき、安全に処理を止めること」であり、「なんでもcatchして進めること」ではありません。
正しい例外処理の考え方
以下のような方針が重要です。
✅ 明示的に発生が予想される例外はcatchする
例:
IOException
(ファイルやネットワークのエラー)SQLException
(データベースアクセス時)
❌ バグの可能性がある例外はcatchしない
- ロジックミスは設計段階で修正する
- 単なるcatchでごまかさない
✅ catchする場合は、ログ記録+再スローを検討
try {
doSomething();
} catch (IOException e) {
logger.error("ファイル処理失敗", e);
throw e; // 呼び出し元で再処理
}
よくある誤解とアンチパターン
catch (Exception e) {}
のようなcatchは、すべての例外を握りつぶしてしまうため危険です。e.printStackTrace()
だけのcatchは、本番環境では何も記録に残らない可能性があります。
まとめ
NullPointerException
やIllegalArgumentException
など、catchすべきでない例外は意外と多い- それらは多くが設計・ロジックミスに起因し、catchすること自体が間違いの隠蔽につながる
- 「例外は設計で防ぐ。catchは最終手段」という姿勢が重要
Javaでの堅牢な例外設計を目指すなら、例外の意味と役割を理解し、「catchすることの是非」を常に意識することが重要です。