Menu
Coddy logo textTech

Hierarchie der Exception-Klassen

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 59 von 87.

Javas System zur Ausnahmebehandlung basiert auf einer gut organisierten Klassenhierarchie, deren Wurzel die Klasse Throwable ist. Das Verständnis dieser Hierarchie hilft dir, Ausnahmen effektiver abzufangen und zu behandeln.

An der Spitze steht Throwable, der Elternteil aller Ausnahmen und Fehler. Es hat zwei direkte Unterklassen:

Throwable
├── Error          // Schwere Probleme (diese nicht abfangen)
└── Exception      // Behebbare Probleme
    └── RuntimeException  // Ungeprüfte Exceptions

Fehler steht für schwerwiegende Probleme, die Anwendungen nicht zu behandeln versuchen sollten, wie etwa OutOfMemoryError oder StackOverflowError. Diese weisen auf grundlegende Probleme mit der JVM selbst hin.

Exception ist der Zweig, mit dem du am häufigsten arbeiten wirst. Er teilt sich in zwei Kategorien: geprüfte Ausnahmen (direkte Unterklassen von Exception) und ungeprüfte Ausnahmen (Unterklassen von RuntimeException).

// Häufige Exception-Klassen
Exception
├── IOException           // Datei-/Netzwerkprobleme
├── SQLException          // Datenbankprobleme
└── RuntimeException
    ├── NullPointerException
    ├── ArrayIndexOutOfBoundsException
    └── IllegalArgumentException

Da exceptions classes sind, folgen sie den Vererbungsregeln. Wenn du einen übergeordneten exception-Typ abfängst, fängst du auch alle seine untergeordneten Typen ab:

try {
    // etwas Code
} catch (Exception e) {
    // Fängt ALLE Exceptions ab (normalerweise zu breit)
}
try {
    // etwas Code
} catch (RuntimeException e) {
    // Catches only runtime exceptions and subclasses
}

Diese Hierarchie ermöglicht es dir, bei der Fehlerbehandlung so spezifisch oder allgemein vorzugehen, wie es nötig ist, und sie bildet die Grundlage für die Erstellung deiner eigenen benutzerdefinierten Ausnahmen.

challenge icon

Aufgabe

Einfach

Lass uns einen Exception-Analyzer erstellen, der zeigt, wie die Exception-Hierarchie von Java in der Praxis funktioniert! Du erstellst ein System, das Exceptions auf unterschiedlichen Ebenen der Spezifität abfängt und meldet, welcher Typ abgefangen wurde.

Du organisierst deinen Code über drei Dateien:

  • ExceptionThrower.java: Erstelle eine Klasse, die abhängig von der Eingabe verschiedene Exception-Typen auslösen kann. Deine Klasse sollte drei statische Methoden enthalten:

    triggerRuntime(String type) – Wirf abhängig vom Typ-String verschiedene Runtime-Exceptions:

    • Wenn type "null" ist, wirf eine NullPointerException mit der Nachricht "Null value encountered"
    • Wenn type "index" ist, wirf eine ArrayIndexOutOfBoundsException mit der Nachricht "Invalid index"
    • Wenn type "argument" ist, wirf eine IllegalArgumentException mit der Nachricht "Bad argument"

    triggerArithmetic() – Wirf eine ArithmeticException mit der Nachricht "Division error"

    triggerGeneric() – Wirf eine IllegalStateException mit der Nachricht "Generic runtime error" (ihre Hierarchie ist Exception > RuntimeException > IllegalStateException)

  • ExceptionAnalyzer.java: Erstelle eine Klasse, die Exceptions auf unterschiedlichen Ebenen der Hierarchie abfängt und erkennt, was abgefangen wurde. Füge diese statischen Methoden hinzu:

    analyzeSpecific(String type) – Rufe ExceptionThrower.triggerRuntime(type) innerhalb eines try-Blocks auf. Verwende separate catch-Blöcke für NullPointerException, ArrayIndexOutOfBoundsException und IllegalArgumentException. Gib für jeden aus: Caught specific: [exception class simple name], gefolgt von Message: [exception message]

    analyzeWithParent() – Rufe ExceptionThrower.triggerArithmetic() innerhalb eines try-Blocks auf. Fange sie mit RuntimeException (dem übergeordneten Typ) ab. Gib Caught via parent: RuntimeException aus, gefolgt von Actual type: [exception class simple name]

    analyzeWithGrandparent() – Rufe ExceptionThrower.triggerGeneric() innerhalb eines try-Blocks auf. Fange sie mit Exception (weiter oben in der Hierarchie) ab. Gib Caught via grandparent: Exception aus, gefolgt von Actual type: [exception class simple name]

  • Main.java: Führe deinen Exception-Analyzer zusammen! Du erhältst eine Eingabe: einen Exception-Typ-String (entweder "null", "index" oder "argument").

    Gib zuerst === Specific Catch === aus und rufe analyzeSpecific mit deiner Eingabe auf.

    Gib dann eine leere Zeile und === Parent Catch === aus und rufe analyzeWithParent auf.

    Gib schließlich eine leere Zeile und === Grandparent Catch === aus und rufe analyzeWithGrandparent auf.

Du erhältst eine Eingabe: den auszulösenden Exception-Typ ("null", "index" oder "argument").

Verwende e.getClass().getSimpleName(), um den Klassennamen der Exception abzurufen, und e.getMessage(), um ihre Nachricht abzurufen. Diese Herausforderung zeigt, dass das Abfangen eines übergeordneten Exception-Typs auch alle seine untergeordneten Typen abfängt – ein wichtiges Konzept bei der Entscheidung, wie spezifisch dein Exception-Handling sein sollte!

Probier es selbst

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: Gib eine leere Zeile aus, dann "=== Parent Catch ===", dann rufe ExceptionAnalyzer.analyzeWithParent() auf
        
        // TODO: Print a blank line, then "=== Grandparent Catch ===", then call ExceptionAnalyzer.analyzeWithGrandparent()
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Java-Compiler