Javaの例外処理、アプリが落ちる原因を見抜けていますか?
Javaでプログラムを書いていると、「コンパイルは通ったのに、実行したら突然エラーで止まった…」なんて経験、ありませんか?
これは「例外(Exception)」という仕組みの一つで、Javaにはこの例外にも2つの種類があり、それぞれ発生のタイミングや備え方が違うんです。
この違いを知らずにいると、プログラムが思わぬところで止まったり、意味もなくtry-catchを書いてしまったりと、初心者にありがちなつまずきポイントになってしまいます。
そこで今回は、Javaでよく登場するRuntimeException(実行時例外)とCheckedException(コンパイル時例外)について、具体的なコード例とやさしい言葉でじっくり解説していきます。
この記事で学べること
- Javaにおける例外とは何か
- RuntimeExceptionとCheckedExceptionの違い
- よくあるRuntimeExceptionの例とやさしい対策
- CheckedExceptionに対する備え方と考え方
- try-catchが必要な場面・不要な場面の見分け方
Javaの例外処理は“2種類”あるって知ってた?
Javaでは、例外(Exception)は次の2種類に分かれています。
種類 | 発生のタイミング | 対応の必要性 | 主な原因 |
---|---|---|---|
RuntimeException | 実行して初めて発生 | 任意 | コーディングミス |
CheckedException | コンパイル時に警告 | 必須 | 外部環境の不安定さ |
Javaがこの2つに分けた理由は?
「プログラマーが気をつければ防げるミス」と「どんなに頑張っても起こるかもしれないトラブル」は、別物ですよね。
Javaはそれを見分けてくれて、前者は“自分で注意して”、後者は“あらかじめ備えて”という考え方を取り入れているんです。
RuntimeExceptionとは? ― 書き方のミスが原因で発生する例外
特徴
RuntimeExceptionは、プログラムの実行中に発生する例外で、多くは「書いたコードの不備」が原因です。
Javaはこれを「ちゃんと注意して書いてね」というスタンスで、try-catchを書かなくてもコンパイルは通ります。
よくあるRuntimeExceptionの例と対策
1. NullPointerException(通称ぬるぽ)
String name = null;
System.out.println(name.length());
このコード、書いたときは問題なさそうに見えますが、実行するとnullのままメソッドを呼び出していることに気づかず、エラーで止まってしまいます。
こういうときは、事前にnullかどうかをチェックしておくと安心です。
if (name != null) {
System.out.println(name.length());
}
2. ArrayIndexOutOfBoundsException
int[] nums = {1, 2, 3};
System.out.println(nums[3]);
配列のインデックスは0から始まるので、3番目を指定すると存在しない位置を参照しようとしてエラーになります。
まずはlengthなどで範囲内かどうかを確認してからアクセスする習慣をつけましょう。
3. NumberFormatException
String age = "abc";
int value = Integer.parseInt(age);
一見数字に見えるかもしれませんが、実は文字列が数値として扱えないと変換時にエラーになります。
事前に数字だけかどうかをチェックすることで回避できます。
if (age.matches("\\d+")) {
int value = Integer.parseInt(age);
}
4. ClassCastException
Object obj = "hello";
Integer num = (Integer) obj;
実際にはStringなのに、Integerとしてキャストしようとすると実行時にエラーになります。
キャストする前に、正しい型かどうかを確認してからにしましょう。
if (obj instanceof Integer) {
Integer num = (Integer) obj;
}
5. IllegalArgumentException
Thread t = new Thread();
t.setPriority(100);
優先度は1〜10までと決まっているのに、100を指定すると不正な引数としてエラーになります。
引数に制限があるメソッドでは、値の範囲を調べてから渡すのがポイントです。
6. ArithmeticException
int result = 10 / 0;
数学と同じで、0で割るとエラーになります。
分母が0でないかをチェックしてから計算しましょう。
if (denominator != 0) {
int result = numerator / denominator;
}
RuntimeExceptionのまとめ
- try-catchは強制されないが、実行すると落ちる可能性がある
- 多くは「防げるミス」。nullチェックやバリデーションで回避できる
- 落ちる前に“気づけるコード”を書く意識を持とう
CheckedExceptionとは? ― 外部に関わる処理は「備え」が必要
特徴と考え方
CheckedExceptionは、ファイル操作・ネットワーク通信・データベース接続など外部要因に左右される処理で発生します。
外部とのやりとりは、どれだけ丁寧に書いても失敗することがあります。
だからこそJavaは「ここはtry-catchでちゃんと備えてね」と、強制的にエラーハンドリングを書くよう促してくれるのです。
例:ファイルを読み込もうとすると
FileReader reader = new FileReader("data.txt");
このコードは、ファイルが存在しない場合にFileNotFoundException
が発生します。
方法①:try-catchで受け止める
try {
FileReader reader = new FileReader("data.txt");
} catch (FileNotFoundException e) {
System.out.println("ファイルが見つかりませんでした。");
}
こうしておけば、ファイルがなかったとしてもプログラムが止まらず、次の処理に進めるようになります。
方法②:throwsで呼び出し元に伝える
public void readFile() throws FileNotFoundException {
FileReader reader = new FileReader("data.txt");
}
このように宣言しておくと、「このメソッドを使うときは、呼び出し側で例外に対応してね」と伝えることができます。
よくあるCheckedException
CheckedExceptionは、実行時に起こる可能性のあるトラブルを、あらかじめコード上で「想定」しておくために用いられます。たとえば、ファイルの読み書きやデータベースとのやりとりなどは、どんなに自分のコードが正しくても外部要因で失敗することがありますよね。
Javaではそういった「失敗するかもしれない処理」に対して、try-catch文で明示的に対応するようルール化されています。ここでは、代表的なCheckedExceptionをいくつか紹介します。
IOException
(ファイルやネットワーク)SQLException
(データベース)ParseException
(日付や数値の変換)
CheckedExceptionのまとめ
- try-catchまたはthrowsが必須
- 外部環境の変化に強いコードを書くための設計思想
- 「失敗するかもしれない前提」で考えることが大切
RuntimeとChecked、どう違うの? 比較してみよう!
項目 | RuntimeException | CheckedException |
発生タイミング | 実行して初めてわかる | 実行時に起きるが事前に備える |
try-catchの必要性 | 任意 | 必須 |
主な原因 | コードミス | 外部要因 |
対応の考え方 | 未然に防ぐ | 起きる前提で備える |
まとめ:例外の種類を知れば、もっと安心してコードが書ける
種類 | try-catch必要? | 主な原因 | 例 | 対策の方向性 |
RuntimeException | 任意 | コーディングミス | NullPointerExceptionなど | チェックやバリデーションで予防 |
CheckedException | 必須 | 外部の失敗リスク | IOExceptionなど | try-catchやthrowsで対応 |
例外は怖いものではありません。むしろ「ちゃんと失敗できる」ようにすることで、落ちない、壊れない、信頼されるコードを書けるようになります。
エラーと仲良くなれるよう、まずはこの“2種類の例外”から覚えていきましょう!