結論
- 例外処理は「構文・分類・制約」を正確に覚える科目
- 特に チェック例外 / 非チェック例外の違い と
try-catch-finallyの挙動 が頻出 - 「コンパイルエラーか?実行時例外か?」を即判定できるかが合否を分ける
例外とは何か
Java の例外は、プログラム実行中に発生する 異常状態をオブジェクトとして扱う仕組み。
すべての例外は次の継承関係に属する。
Object
└─ Throwable
├─ Error
└─ Exception
└─ RuntimeException
Error と Exception の違い
Error
- JVM レベルの致命的な問題
- プログラムで対処しない前提
- 例:
OutOfMemoryError
Exception
- アプリケーションで対処可能な異常
-
try-catchで処理する対象
チェック例外と非チェック例外
チェック例外(Checked Exception)
- コンパイル時にチェックされる
- 処理しないとコンパイルエラー
- 代表例:
IOExceptionSQLException
void sample() throws IOException {
// throws が必要
}
非チェック例外(Unchecked Exception)
-
RuntimeExceptionのサブクラス - コンパイルは通る
- 実行時に落ちる可能性がある
- 代表例:
NullPointerExceptionArrayIndexOutOfBoundsException
try-catch-finally の基本構文
try {
// 例外が発生する可能性のある処理
} catch (Exception e) {
// 例外発生時の処理
} finally {
// 必ず実行される
}
finally の重要ポイント
-
returnがあっても実行される - 例外が起きても起きなくても実行される
-
tryまたはcatchが必須(finally単体は不可)
catch の並び順ルール(超重要)
- サブクラス → スーパークラスの順
- 逆にするとコンパイルエラー
// NG
try {
// ...
} catch (Exception e) {
} catch (IOException e) { // 到達不能コードでコンパイルエラー
}
multi-catch
try {
// ...
} catch (IOException | SQLException e) {
}
制約
-
catch変数は暗黙的にfinal - 親子関係にある例外型は同じ
multi-catchに並べられない
throws と throw の違い
throws
- 「このメソッドは例外を投げる可能性があります」という 宣言
- メソッド定義に書く
void sample() throws IOException {
}
throw
- 実際に例外を 送出するキーワード
void sample() throws IOException {
throw new IOException();
}
オーバーライド時の例外ルール(頻出)
オーバーライド先メソッドで:
- より広いチェック例外は投げられない
- 同じか、より狭いチェック例外のみ可
- 非チェック例外(
RuntimeException系)は制限なし
try-with-resources
try (BufferedReader br = new BufferedReader(...)) {
// 処理
}
ポイント
- ブロック終了時に 自動的に
close()が呼ばれる - 対象は
AutoCloseableを実装しているクラス -
close()はtryブロック終了後に実行
試験でよくあるひっかけ
- チェック例外の処理漏れ → コンパイルエラー
-
catchの順序ミス(親子関係の逆順) -
finallyが実行されるかどうかの誤解 -
throwsとthrowの混同 -
RuntimeExceptionを checked だと思い込む
まとめ
- Java Silver の例外処理は 「暗記+即判定」の世界
- 実務的な深掘りより、ルールの正確な理解 が最重要
- 常に 「これはコンパイルエラー?実行時例外?」 を意識して問題を解く
例外処理は「なんとなく理解したつもり」だと落とされがちですが、
構文・分類・制約をパターンとして覚えることで、一気に得点源になります。