はじめに:例外はただのエラーじゃない!
Javaでプログラムを書いていると必ず出てくる「例外(Exception)」。
でも、「チェック例外と非チェック例外の違いがよく分からない…」「どう使い分けるの?」と悩む方も多いです。
このブログでは、Java初心者でもわかるように:
- チェック例外と非チェック例外の違い
- 実務での使い分け方
- 使い分けの判断ポイント
- よくある失敗とその回避法
をやさしく、丁寧に解説します!
1. チェック例外と非チェック例外の違いって?
✔ チェック例外(Checked Exception)
Exceptionを継承- コンパイル時に明示的な対応が必要
- メソッドに
throwsを書くか、try-catchで捕まえる必要あり - 代表例:
IOException,SQLException,FileNotFoundException
|
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(); } |
✔ 非チェック例外(Unchecked Exception)
RuntimeExceptionを継承- コンパイル時の対応が不要
- 呼び出し側が対処していなくてもコンパイルは通る
- 代表例:
NullPointerException,IllegalArgumentException,IndexOutOfBoundsException
|
1 2 3 4 5 6 7 |
public void setAge(int age) { if (age < 0) { throw new IllegalArgumentException("年齢は0以上である必要があります"); } this.age = age; } |
2. 実務ではどう使い分けるの?
✔ ポイントは「呼び出し側が対処できるか?」
| 状況 | 使うべき例外 |
|---|---|
| ファイルが存在しない | チェック例外(呼び出し元で代替処理できる) |
| 引数が不正(nullなど) | 非チェック例外(呼び出し元の設計ミス) |
| DBが一時的に落ちている | チェック例外(リトライできる可能性あり) |
| 配列の範囲外アクセス | 非チェック例外(コードバグ) |
3. 具体的なコードで違いを体感!
✔ チェック例外の使い方(ファイル読み込み)
|
1 2 3 4 5 |
public String loadConfig(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); return br.readLine(); } |
→ 呼び出し元でIOExceptionの対処が強制される:
|
1 2 3 4 5 6 |
try { String config = loadConfig("config.txt"); } catch (IOException e) { System.out.println("設定ファイル読み込み失敗"); } |
✔ 非チェック例外の使い方(引数バリデーション)
|
1 2 3 4 5 6 7 |
public void setUsername(String name) { if (name == null || name.isEmpty()) { throw new IllegalArgumentException("ユーザー名は必須です"); } this.name = name; } |
→ 呼び出し元で対応は強制されないが、設計上は呼び出し側の責任。
4. 実務的な使い分けの判断フロー
|
1 2 3 4 5 6 7 8 |
↓ 呼び出し元がエラーに対応可能? → Yes:チェック例外 → No ↓ ↓ それはプログラムミスか?引数・状態の問題? → Yes:非チェック例外 → No:ケースに応じて設計判断 |
✔ 例:
- 外部ファイルが無い → 代替ファイル読み込みなど可能 → チェック例外
- 引数がnull → 仕様違反であり呼び出し側のバグ → 非チェック例外
5. よくある実務コードパターン
✔ 非チェック例外で設計ミスを伝える
|
1 2 3 4 5 6 7 |
public void saveUser(String name) { if (name == null) { throw new NullPointerException("name は null にできません"); } // 保存処理… } |
✔ チェック例外で処理を委ねる
|
1 2 3 4 5 |
public void connectToDb() throws SQLException { Connection conn = DriverManager.getConnection("jdbc:mysql://..."); // 処理… } |
→ 呼び出し元に「接続に失敗する可能性があるよ」と伝えられる
6. ラップして再スロー:例外設計の柔軟さ
✔ チェック例外 → 非チェック例外に変換
|
1 2 3 4 5 6 7 8 |
public void loadData() { try { readFile(); } catch (IOException e) { throw new RuntimeException("読み込み失敗", e); } } |
→ 呼び出し元にチェック例外を強制したくないときに使われるテクニック
7. 実務でのベストプラクティス
| 状況 | 対応策 |
|---|---|
| 呼び出し元が対応できる外部要因 | チェック例外にする |
| 呼び出し元が対応しようがない設計ミス | 非チェック例外にする |
| ライブラリ設計者なら | 例外の種類を明確にしてドキュメントに記載する |
| チェック例外が伝播しすぎるなら | ラップして非チェックにまとめるのもアリ |
8. よくあるアンチパターンと注意点
- ❌ 何でも非チェック例外にする
→ 呼び出し元が予期しないクラッシュを招くことに - ❌ チェック例外をthrowsだけして実質何もしない
→ 呼び出し元での例外処理設計が曖昧に - ❌ try-catchで例外を握りつぶす
|
1 2 3 4 5 6 |
try { method(); } catch (Exception e) { // なにも処理しない } |
→ これはバグの温床です!
9. まとめ:チェック例外と非チェック例外の正しい使い分け
| 比較項目 | チェック例外 | 非チェック例外 |
|---|---|---|
| コンパイル時の強制 | あり | なし |
| 呼び出し元の対応想定 | 可能 | 困難 or 不要 |
| 主な例外 | IOException, SQLException | NullPointerException, IllegalArgumentException |
| 想定される原因 | 外部要因、回復可能 | プログラムミス、回復困難 |
| API設計向けか | 明示的に対処を促したいとき | 軽く済ませたい/深刻なエラー |
おわりに:例外設計こそがプロの証
例外はただの「エラー処理」ではありません。
システムの信頼性と開発効率を左右する重要な設計要素です。
これからJavaで仕事をしたい人、転職を目指す人は、まずは:
で、例外の基本からしっかり学びましょう。
さらに、
- 設計やレビューが不安な人
- もっと実務寄りなコードを学びたい人
- Javaで転職を成功させたい人
には、サイゼントアカデミー があなたの味方です!

完全ガイド|実務で使える設計指針とサンプルコード集-120x68.png)
コメント