Menu
Coddy logo textTech

例外クラスの階層構造

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

Java の例外処理システムは、Throwable クラスをルートとする、よく整理されたクラス階層に基づいて構築されています。この階層を理解すると、例外をより効果的に捕捉して処理できるようになります。

最上位にあるのは、すべての例外とエラーの親である Throwable です。直接のサブクラスは2つあります。

Throwable
├── Error          // 深刻な問題(これらはキャッチしないでください)
└── Exception      // 回復可能な問題
    └── RuntimeException  // 非チェック例外

Error は、アプリケーションが処理しようとすべきではない重大な問題を表します。たとえば、OutOfMemoryErrorStackOverflowError です。これらは、JVM 自体に根本的な問題があることを示します。

Exception は、最も頻繁に扱うことになるブランチです。これは、検査例外(Exception の直接のサブクラス)と非検査例外(RuntimeException のサブクラス)の2つのカテゴリに分かれます。

// 一般的な例外クラス
Exception
├── IOException           // ファイル/ネットワークの問題
├── SQLException          // データベースの問題
└── RuntimeException
    ├── NullPointerException
    ├── ArrayIndexOutOfBoundsException
    └── IllegalArgumentException

exceptions は classes なので、継承ルールに従います。親の exceptions 型を catch すると、そのすべての子も catch します。

try {
    // いくつかのコード
} catch (Exception e) {
    // すべての例外をキャッチする(通常は広すぎる)
}
try {
    // いくつかのコード
} catch (RuntimeException e) {
    // Catches only runtime exceptions and subclasses
}

この hierarchy により、エラーを処理する際に必要に応じて具体的にも一般的にもでき、独自のカスタム exceptions を作成するための基盤となります。

challenge icon

チャレンジ

簡単

Java の exception hierarchy が実際にどのように機能するかを示す exception analyzer を構築しましょう!異なる specificity のレベルで exception を捕捉し、どの型が捕捉されたかを報告するシステムを作成します。

コードを 3 つのファイルに分けて構成します。

  • ExceptionThrower.java:入力に基づいてさまざまな種類の exception を発生させられる class を作成します。この class には、次の 3 つの static メソッドを用意します。

    triggerRuntime(String type) - type 文字列に基づいて、異なる runtime exception を throw します。

    • type が "null" の場合、メッセージ "Null value encountered" を持つ NullPointerException を throw します
    • type が "index" の場合、メッセージ "Invalid index" を持つ ArrayIndexOutOfBoundsException を throw します
    • type が "argument" の場合、メッセージ "Bad argument" を持つ IllegalArgumentException を throw します

    triggerArithmetic() - メッセージ "Division error" を持つ ArithmeticException を throw します

    triggerGeneric() - メッセージ "Generic runtime error" を持つ IllegalStateException を throw します(その hierarchy は Exception > RuntimeException > IllegalStateException です)

  • ExceptionAnalyzer.java:異なる hierarchy のレベルで exception を捕捉し、何が捕捉されたかを特定する class を作成します。次の static メソッドを含めます。

    analyzeSpecific(String type) - ExceptionThrower.triggerRuntime(type) を try ブロック内で呼び出します。NullPointerExceptionArrayIndexOutOfBoundsExceptionIllegalArgumentException 用に個別の catch ブロックを使用します。それぞれについて、Caught specific: [exception class simple name] に続けて Message: [exception message] を出力します。

    analyzeWithParent() - ExceptionThrower.triggerArithmetic() を try ブロック内で呼び出します。RuntimeException(parent 型)を使って捕捉します。Caught via parent: RuntimeException に続けて Actual type: [exception class simple name] を出力します。

    analyzeWithGrandparent() - ExceptionThrower.triggerGeneric() を try ブロック内で呼び出します。hierarchy のさらに上位にある Exception を使って捕捉します。Caught via grandparent: Exception に続けて Actual type: [exception class simple name] を出力します。

  • Main.java:exception analyzer をまとめて動作させます!入力として 1 つの exception type 文字列("null""index"、または "argument" のいずれか)を受け取ります。

    まず、=== Specific Catch === を出力し、入力を使って analyzeSpecific を呼び出します。

    次に空行を出力し、=== Parent Catch === を出力して、analyzeWithParent を呼び出します。

    最後に空行を出力し、=== Grandparent Catch === を出力して、analyzeWithGrandparent を呼び出します。

発生させる exception type("null""index"、または "argument")を 1 つ入力として受け取ります。

e.getClass().getSimpleName() を使用して exception の class 名を取得し、e.getMessage() を使用してそのメッセージを取得します。この challenge では、parent exception type を捕捉すると、そのすべての子も捕捉されることを示します。これは、exception handling をどの程度具体的にするかを決める際の重要な概念です!

自分で試してみよう

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String type = scanner.nextLine();
        
        // TODO: Print "=== Specific Catch ===" and call ExceptionAnalyzer.analyzeSpecific(type)
        
        // TODO: 空行を出力し、次に "=== Parent Catch ===" を出力してから、ExceptionAnalyzer.analyzeWithParent() を呼び出す
        
        // TODO: Print a blank line, then "=== Grandparent Catch ===", then call ExceptionAnalyzer.analyzeWithGrandparent()
    }
}
quiz icon腕試し

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

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

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