検査例外と非検査エラー
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 exceptions は RuntimeException を拡張します。コンパイラーは、それらを 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 を使用します。
チャレンジ
簡単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 にはthrowsdeclaration が必要ないことに注意してください。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]"
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造自分で練習してみよう: Javaオンラインコンパイラ