例外処理とは、プログラムの実行中に発生するエラーや予期しない事態に対処するための仕組みのこと。例外処理を適切にプログラムに組み込むことで、プログラムがエラーで突然止まってしまうのを防いだり、エラーが発生しても適切にプログラムの実行を続けることができたりするようになります。
例えばほとんどのプログラミング言語に共通する事象として「0で割り算をしようとするとエラーが発生する」というものがあります。これを例外処理なしで実行すると、プログラムはそこで止まってしまいます。
が、しかし、例外処理を使えばこのエラーを検知して「エラーが発生しました」というメッセージを表示し、プログラムを続行できます。
0で割り算をする、という以外にも自分で新たな例外を作成することで、例えば「年齢は0以上でなければならない」というルールを守らない入力があった場合に、専用のエラーメッセージを表示することができるようになります。
このページでは、この例外処理をJavaで実現する方法(try-catch構文)の使い方やコツ・注意点を初心者向けにわかりやすく解説します。
関連 Javaの1stステップ:基本的な構文ルールを1分で復習!
try-catchの基本構文
Javaではプログラム中にエラーが発生する可能性のある部分をtryブロックで囲み、エラーが発生した場合の処理をcatchブロックで定義することで例外処理を利用することができるようになります。
以下は、try-catchの基本的な使い方を示す例。
この例では、0で割り算を行い、発生したエラーをキャッチして処理しています。
public class TryCatchExample { public static void main(String[] args) { try { // 例外が発生する可能性のあるコード int result = 10 / 0; } catch (ArithmeticException e) { // 例外が発生した場合の処理 System.out.println("エラーが発生しました: " + e.getMessage()); } } } // 出力結果: // エラーが発生しました: / by zero
この例では10を0で割ろうとしていますが、これは「ArithmeticException」というエラーを引き起こします。tryブロック内でエラーが発生すると、プログラムはcatchブロックに移り「ArithmeticException」が発生した場合にエラーメッセージを表示する仕組み。
このように、try-catchを使うことで、エラーが発生してもプログラムを停止させず、適切なエラーメッセージを表示して処理を続行することができます。
ポイント try-catchの構文ルール
try { // 例外が発生する可能性のあるコード } catch (例外の種類 例外の変数) { // 例外が発生した場合の処理 }
- tryブロック: 例外が発生する可能性のあるコードを囲む。
- catchブロック: 例外が発生した場合に実行されるコードを定義。
複数のcatchブロック
Javaでは、複数の異なる種類の例外をキャッチするために複数のcatchブロックを使用することができるため、異なる種類のエラーに対して異なる処理を行うことも可能です。
↓の例では、配列の範囲外アクセスを試みています。最初のcatchブロックが「ArrayIndexOutOfBoundsException」をキャッチし「配列のインデックスが範囲外です」というメッセージを表示します。もし他の種類の例外が発生した場合は、次のcatchブロックでキャッチされ、「その他のエラー」というメッセージを表示します。
public class MultipleCatchExample { public static void main(String[] args) { try { int[] numbers = {1, 2, 3}; System.out.println(numbers[5]); // 配列の範囲外アクセス } catch (ArrayIndexOutOfBoundsException e) { // 配列の範囲外アクセスが発生した場合の処理 System.out.println("配列のインデックスが範囲外です: " + e.getMessage()); } catch (Exception e) { // その他の例外が発生した場合の処理 System.out.println("その他のエラー: " + e.getMessage()); } } } // 出力結果: // 配列のインデックスが範囲外です: Index 5 out of bounds for length 3
このように、複数のcatchブロックを使うことで、異なる種類の例外に対して適切なエラーハンドリングを行うことができます。
ポイント 複数のcatchブロックを利用するパターンの構文ルール
try { // 例外が発生する可能性のあるコード } catch (具体的な例外1 例外の変数) { // 具体的な例外1が発生した場合の処理 } catch (具体的な例外2 例外の変数) { // 具体的な例外2が発生した場合の処理 } catch (一般的な例外 例外の変数) { // その他の例外が発生した場合の処理 }
- 複数のcatchブロック: tryブロック内で発生する可能性のある異なる種類の例外ごとにcatchブロックを定義する。
- 例外の順序: より具体的な例外から順に記述し、最後に一般的な例外をキャッチするcatchブロックを記述する。
finallyブロック
Javaの例外処理では、finallyブロックを使用して、例外の発生有無にかかわらず必ず実行されるコードを定義することができます。リソースの解放や後処理など、どんな状況でも実行しておきたい処理を記述するために用いられます。
以下は、finallyブロックの基本的な使い方を示す例。この例では、0で割り算を行い、発生したエラーをキャッチした後、必ず実行される処理をfinallyブロックで定義しています。
public class FinallyExample { public static void main(String[] args) { try { // 例外が発生する可能性のあるコード int result = 10 / 0; } catch (ArithmeticException e) { // 例外が発生した場合の処理 System.out.println("エラーが発生しました: " + e.getMessage()); } finally { // 必ず実行される処理 System.out.println("このコードは必ず実行されます。"); } } } // 出力結果: // エラーが発生しました: / by zero // このコードは必ず実行されます。
ポイント finallyブロックの使い方
try { // 例外が発生する可能性のあるコード } catch (例外の種類 例外の変数) { // 例外が発生した場合の処理 } finally { // 必ず実行される処理 }
- tryブロック: エラーが発生する可能性のあるコードを囲む。
- catchブロック: エラーが発生した場合に実行されるコードを定義する。
- finallyブロック: 例外の有無にかかわらず必ず実行されるコードを定義する。
カスタム例外
Javaでは標準で提供される例外クラス(例:NullPointerException
やArrayIndexOutOfBoundsException
)を使ってエラーを処理することができますが、同時に特定のアプリケーションに合わせて独自の例外を作成することも可能です。これを「カスタム例外」と呼びます。カスタム例外を使うことで、特定のエラー状況に対してよりわかりやすく、意味のあるエラーメッセージを提供することができます。
カスタム例外は、Javaの標準例外クラスを継承して作成する独自の例外クラスです。これにより、特定のビジネスロジックやアプリケーションの要件に応じたエラー処理を行うことができます。例えば、年齢が負の値になってはいけないというルールを守らない入力があった場合に、専用のエラーメッセージを提供するためにカスタム例外を作成します。
参考 Java「クラス」とは? / Java「クラスの継承」とは?
カスタム例外の作成
- カスタム例外クラスの定義
- 標準の例外クラス(例:
Exception
やRuntimeException
)を継承して新しいクラスを作成する
- 標準の例外クラス(例:
- カスタム例外の使用
- 必要に応じて、カスタム例外をスロー(throw)し、catchブロックで処理。
早速、カスタム例外を作成してみます。
まず、カスタム例外クラスを定義します。このクラスはException
クラスを継承します。
// カスタム例外クラスの定義 public class CustomException extends Exception { public CustomException(String message) { super(message); } }
次に、カスタム例外をスローし、catchブロックで処理します。この例では、入力された値が0未満の場合にカスタム例外をスローします。
public class CustomExceptionExample { public static void main(String[] args) { try { checkValue(-1); } catch (CustomException e) { // カスタム例外が発生した場合の処理 System.out.println("カスタム例外が発生しました: " + e.getMessage()); } } // 値をチェックし、条件に合わない場合にカスタム例外をスローするメソッド public static void checkValue(int value) throws CustomException { if (value < 0) { throw new CustomException("値は0以上でなければなりません。"); } } } // 出力結果: // カスタム例外が発生しました: 値は0以上でなければなりません。
checkValue
メソッドが負の値を受け取ると、CustomException
をスローするというコード。main
メソッド内でこのメソッドを呼び出し、カスタム例外がスローされた場合はcatchブロックで処理します。このように、カスタム例外を使用することで、特定のエラー状況に対して意味のあるエラーメッセージを提供し、プログラムの可読性とメンテナンス性を向上させることができます。
ポイント throwの構文ルール
throw new 例外クラス名("エラーメッセージ");
- throw キーワード: 例外オブジェクトをスローするために使用します。
- 例外オブジェクト:
new
キーワードを使用して例外クラスのインスタンスを作成します。
以下は、throw
キーワードを使用して標準のIllegalArgumentException
をスローする例。
public class ThrowExample { public static void main(String[] args) { checkValue(-1); } public static void checkValue(int value) { if (value < 0) { throw new IllegalArgumentException("値は0以上でなければなりません。"); } System.out.println("値は正しいです: " + value); } } // 出力結果: // Exception in thread "main" java.lang.IllegalArgumentException: 値は0以上でなければなりません。 // at ThrowExample.checkValue(ThrowExample.java:8) // at ThrowExample.main(ThrowExample.java:4)