Menu
Coddy logo textTech

検査例外と非検査エラー

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 61/87。

Java の exception 階層が異なる複数の分岐に分かれていることは、すでに見てきました。理解しておく必要がある重要な違いは、checked exception と未検査 exceptions の違いです。これは、コード内でそれらをどのように handle しなければならないかに影響します。

Checked exceptions は、コンパイラーによって処理を強制される exceptions です。Exception を直接(RuntimeException 経由ではなく)拡張します。これらを catch するか、throws を使って declare する必要があります。

// IOExceptionを処理する必要がある - チェック例外です
public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // IOExceptionをスローする可能性がある
}

// またはキャッチする
public void readFileSafe(String path) {
    try {
        FileReader reader = new FileReader(path);
    } catch (IOException e) {
        System.out.println("File error: " + e.getMessage());
    }
}

Unchecked exceptionsRuntimeException を拡張します。コンパイラーは、それらを handle することを要求しません。これらは通常、null 参照や無効な配列アクセスのようなプログラミングエラーを示します。

// throws宣言は不要
public int divide(int a, int b) {
    return a / b;  // ArithmeticExceptionをスローする可能性がある(非チェック)
}

String name = null;
name.length();  // NullPointerException(非チェック)

カスタム exceptions を作成するときは、呼び出し元がそれらをどのように handle するかに基づいて、親 class を選択します。呼び出し元が予期すべき、回復可能な状態には checked exceptions を使用します。正しいコードでは発生すべきでないプログラミングエラーには、非チェック exceptions を使用します。

challenge icon

チャレンジ

簡単

checked と unchecked exceptions の主な違いを示す年齢検証システムを構築しましょう!両方の種類のカスタム exceptions を作成し、コンパイラーがそれらをどのように異なる方法で扱うかを確認します。

コードを4つのファイルに分けて整理します。

  • InvalidAgeException.java:年齢検証の失敗に対するchecked exceptionを Create します。この exception は Exception を直接拡張する必要があります。つまり、Callers はそれを handle するように forced されます。message を accepts し、親 class に渡す constructor を含めます。
  • NegativeAgeException.java:負の年齢が指定された場合(正しい入力であれば発生すべきでない programming error)に対するunchecked exceptionを Create します。これは RuntimeException を拡張する必要があります。message を accepts して親に渡す constructor を含めます。
  • AgeVerifier.java:両方の exception types を使用して年齢を検証する class を Create します。2つの static methods を含めます。

    verifyAge(int age) - age が 0 未満の場合、この method は message "Age cannot be negative: [age]" を伴う NegativeAgeException(unchecked)を throw する必要があります。age が 18 未満の場合は、message "Must be 18 or older: [age]" を伴う InvalidAgeException(checked)を throw します。それ以外の場合は、Age [age] verified successfully を print します。この method は checked exception を throw するため、throws InvalidAgeException を使用して declaration する必要があります。

    verifyAgeUncheckedOnly(int age) - この method は unchecked exceptions のみを使用します。age が負の場合は、同じ message format で NegativeAgeException を throw します。age が 18 未満の場合は、message "Too young: [age]" を伴う IllegalArgumentException を throw します。それ以外の場合は、Age [age] verified (unchecked method) を print します。この method には throws declaration が必要ないことに注意してください。

  • Main.java:検証システムをまとめます!1つの input、つまり年齢(integer)を受け取ります。

    まず、=== Checked Exception Method === を print し、input の年齢を指定して verifyAge を Call します。これは checked exception を throw するため、try-catch で囲む必要があります。InvalidAgeException を catch し、Checked exception caught: [message] を print します。また、NegativeAgeException も catch し、Unchecked exception caught: [message] を print します。

    次に、空行と === Unchecked Exception Method === を print します。同じ年齢を指定して verifyAgeUncheckedOnly を Call します。この method は exceptions を throw できますが、それらを catch するように forced されてはいません。ただし、errors を適切に handle するため、ここでも try-catch で囲みます。NegativeAgeException を catch し、Runtime exception caught: [message] を print します。IllegalArgumentException を catch し、Illegal argument caught: [message] を print します。

検証する年齢を表す integer を1つの input として受け取ります。

重要な違いに注意してください。checked exception を持つ method では requires a throws declaration and forces Callers to handle it しますが、unchecked method は exception handling がなくても問題なくコンパイルされます。これが Java における checked exceptions と unchecked exceptions の基本的な違いです!

自分で試してみよう

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int age = scanner.nextInt();
        
        // TODO: Test the checked exception method
        // Print: "=== Checked Exception Method ==="
        // try-catch内でAgeVerifier.verifyAge(age)を呼び出す
        // - Catch InvalidAgeException: print "Checked exception caught: [message]"
        // - Catch NegativeAgeException: print "Unchecked exception caught: [message]"
        
        
        // TODO: Print a blank line, then "=== Unchecked Exception Method ==="
        // try-catch内でAgeVerifier.verifyAgeUncheckedOnly(age)を呼び出す
        // - Catch NegativeAgeException: print "Runtime exception caught: [message]"
        // - Catch IllegalArgumentException: print "Illegal argument caught: [message]"
        
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Javaオンラインコンパイラ