はじめに:例外の「全体構造」を知らずに使っていませんか?
Javaでエラーや例外が起きたとき、「Exception」や「RuntimeException」などの用語はよく目にします。
でも、それらがどういう関係にあって、どんな役割を持っているのか、正しく理解できていますか?
このブログでは、初心者の方にもわかりやすく、
- Throwableの意味とは?
- ExceptionとErrorの違いは?
- RuntimeExceptionはどこに入る?
- それぞれ実務でどう使い分けるの?
を、図とコードを使って丁寧に解説します!
1. Javaの例外階層を図で見てみよう!
まずは、Javaの例外・エラーの全体像を図で整理します。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
Object │ ┌────┴────┐ │ │ Throwable その他クラス │ ┌────┴────┐ │ │ Error Exception │ RuntimeException |
この構造が、Javaにおける「すべての例外/エラー処理の基本」となります。
2. Throwableとは何か?
Throwableは、例外やエラーとして「投げられる(throw)」ものの最上位クラスです。
Javaでは、throw new ~で例外を投げるとき、そのインスタンスは必ずThrowableを継承している必要があります。
主なメソッド:
|
1 2 3 4 |
getMessage(); // エラーメッセージ取得 printStackTrace(); // スタックトレース出力 getCause(); // 原因となった例外を取得 |
Throwable自体を直接使うことはあまりありませんが、全体構造を理解する上での「根っこ」となる存在です。
3. Exceptionとは何か?(チェック例外)
Exceptionは、Throwableを継承したクラスで、プログラム中で起こりうる想定内のエラーを表します。
✔ 特徴:
- 多くの場合、呼び出し元で対処が可能
- 発生する可能性をコンパイル時にチェックされる
throws宣言が必要(チェック例外)
✔ 例:
|
1 2 3 4 5 6 |
public void readFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); String line = br.readLine(); br.close(); } |
このように、外部ファイルを読み込む処理は「失敗するかも」が想定されるので、IOExceptionというチェック例外を使います。
4. RuntimeExceptionとは何か?(非チェック例外)
RuntimeExceptionは、Exceptionの中でも特別な位置づけです。
✔ 特徴:
- 実行時に発生(コンパイルではチェックされない)
- 呼び出し元に明示的な対応は不要(
throwsを書かなくてもOK) - バグ・設計ミスの原因であることが多い
✔ よく使われる非チェック例外:
NullPointerExceptionIllegalArgumentExceptionArrayIndexOutOfBoundsException
✔ 例:
|
1 2 3 4 5 |
public void setAge(int age) { if (age < 0) { throw new IllegalArgumentException("年齢は0以上である必要があります"); } } |
5. Errorとは何か?(回復不能なシステムエラー)
Errorは、Throwableを継承するもう一つの重要なクラスです。
✔ 特徴:
- JVMやハードウェアレベルの重大なエラー
- 基本的に回復不能
- アプリケーション側で捕まえる必要なし(むしろ危険)
✔ 例:
OutOfMemoryErrorStackOverflowErrorInternalError
✔ 例外とエラーの違い:
| 分類 | 対応可能性 | 対応方法 |
|---|---|---|
| Exception | 呼び出し元が対処可能 | try-catch / throws |
| Error | 呼び出し元が対処困難 | JVM再起動、アラートなど |
6. 実務での使い分け|判断のポイント
✔ チェック例外(Exception)
- 想定される外部要因(ファイル読み込み、DB接続、ネットワーク断など)
- 呼び出し元が対処できる設計
|
1 2 |
throws IOException |
✔ 非チェック例外(RuntimeException)
- 引数の不正、null、範囲外など、コードの設計ミス
- 呼び出し元ではなく、バグとして修正するべき
|
1 2 |
throw new IllegalArgumentException("不正な値です") |
✔ Error
- 基本的に try-catch で処理しない
- 起きたらシステムログへ出力し、監視や再起動で対応
7. よくある誤解・アンチパターン
❌ 何でも RuntimeException にする
- 呼び出し元での対処が難しくなり、例外の意味がぼやける
❌ Throwable をcatchする
|
1 2 3 4 5 6 |
try { doSomething(); } catch (Throwable t) { // Errorまで握りつぶしてしまう危険 } |
→ Errorも捕まえてしまうため、JVMの異常も無視する恐れあり
❌ catch(Exception e) {} のように空キャッチ
→ ログも出さず、気づかないバグの温床
8. クラス構造まとめ|図解でもう一度おさらい!
|
1 2 3 4 5 6 7 8 9 10 |
Throwable ├── Error(回復不能) │ └── OutOfMemoryError, StackOverflowError ... └── Exception(回復可能) ├── IOException(チェック例外) └── RuntimeException(非チェック例外) ├── NullPointerException ├── IllegalArgumentException └── ... |
このように、Javaの例外構造はきちんと分類されています。
9. 結論|Throwable・Exception・Errorの関係を理解してコードを設計しよう!
例外の全体構造を理解すると:
- より安全でわかりやすいコードが書ける
- 呼び出し元との責任分担が明確になる
- 例外をログやモニタリングに活かせる
これからJavaを本格的に学びたい方は、まずはこの基礎をしっかり押さえてください。
スキルアップの第一歩は「正しい理解」から
- Javaの基礎と応用をしっかり学びたい方には
👉 絶対にJavaプログラマーになりたい人へ。 がオススメ。 - 自分のコードに自信がない、レビューしてほしい、転職も見据えて学びたいなら
👉 サイゼントアカデミー にぜひご相談ください!
完全ガイド|実務で使える設計指針とサンプルコード集-120x68.png)
コメント