Menu
Coddy logo textTech

Exception-Klassenhierarchie

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

Javas Ausnahmebehandlungssystem basiert auf einer gut organisierten Klassenhierarchie, die in der Throwable Klasse verwurzelt ist. Das Verständnis dieser Hierarchie hilft Ihnen dabei, Ausnahmen effektiver abzufangen und zu behandeln.

An der Spitze steht Throwable, die Basisklasse aller Exceptions und Errors. Sie hat zwei direkte Unterklassen:

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

Error repräsentiert schwerwiegende Probleme, die Anwendungen nicht versuchen sollten zu behandeln — wie OutOfMemoryError oder StackOverflowError. Diese weisen auf grundlegende Probleme mit der JVM selbst hin.

Exception ist der Zweig, mit dem Sie am häufigsten arbeiten werden. Er unterteilt sich in zwei Kategorien: geprüfte Exceptions (direkte Unterklassen von Exception) und ungeprüfte Exceptions (Unterklassen von RuntimeException).

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

Da Exceptions Klassen sind, folgen sie den Vererbungsregeln. Wenn Sie einen übergeordneten Exception-Typ abfangen, fangen Sie auch alle seine untergeordneten Typen ab:

try {
    // etwas Code
} catch (Exception e) {
    // Fängt ALLE Exceptions ab (normalerweise zu allgemein)
}
try {
    // etwas Code
} catch (RuntimeException e) {
    // Fängt nur Runtime-Exceptions und Unterklassen ab
}

Diese Hierarchie ermöglicht es Ihnen, bei der Fehlerbehandlung so spezifisch oder allgemein wie nötig vorzugehen, und sie bildet die Grundlage für die Erstellung eigener benutzerdefinierter Exceptions.

challenge icon

Aufgabe

Einfach

Lassen Sie uns einen Exception-Analyzer bauen, der demonstriert, wie die Exception-Hierarchie in Java in der Praxis funktioniert! Sie werden ein System erstellen, das Exceptions auf verschiedenen Spezifitätsebenen abfängt und berichtet, welcher Typ abgefangen wurde.

Sie werden Ihren Code über drei Dateien organisieren:

  • ExceptionThrower.java: Erstellen Sie eine Klasse, die basierend auf der Eingabe verschiedene Arten von Exceptions auslösen kann. Ihre Klasse sollte drei statische Methoden haben:

    triggerRuntime(String type) - Lösen Sie basierend auf dem Typ-String verschiedene Runtime-Exceptions aus:

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

    triggerArithmetic() - Werfen Sie eine ArithmeticException mit der Nachricht "Division error"

    triggerGeneric() - Werfen Sie eine RuntimeException mit der Nachricht "Generic runtime error"

  • ExceptionAnalyzer.java: Erstellen Sie eine Klasse, die Exceptions auf verschiedenen Hierarchieebenen abfängt und identifiziert, was abgefangen wurde. Fügen Sie diese statischen Methoden hinzu:

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

    analyzeWithParent() - Rufen Sie ExceptionThrower.triggerArithmetic() innerhalb eines try-Blocks auf. Fangen Sie diese mit RuntimeException (dem Elterntyp) ab. Geben Sie aus: Caught via parent: RuntimeException gefolgt von Actual type: [exception class simple name]

    analyzeWithGrandparent() - Rufen Sie ExceptionThrower.triggerGeneric() innerhalb eines try-Blocks auf. Fangen Sie diese mit Exception (noch höher in der Hierarchie) ab. Geben Sie aus: Caught via grandparent: Exception gefolgt von Actual type: [exception class simple name]

  • Main.java: Bringen Sie Ihren Exception-Analyzer zusammen! Sie erhalten eine Eingabe: einen Exception-Typ-String (entweder "null", "index" oder "argument").

    Geben Sie zuerst === Specific Catch === aus und rufen Sie analyzeSpecific mit Ihrer Eingabe auf.

    Geben Sie dann eine Leerzeile und === Parent Catch === aus und rufen Sie analyzeWithParent auf.

    Geben Sie schließlich eine Leerzeile und === Grandparent Catch === aus und rufen Sie analyzeWithGrandparent auf.

Sie erhalten eine Eingabe: den auszulösenden Exception-Typ ("null", "index" oder "argument").

Verwenden Sie e.getClass().getSimpleName(), um den Klassennamen der Exception zu erhalten, und e.getMessage(), um deren Nachricht abzurufen. Diese Herausforderung zeigt, wie das Abfangen eines Eltern-Exception-Typs auch alle seine Kinder abfängt – ein Schlüsselkonzept bei der Entscheidung, wie spezifisch Ihre Exception-Behandlung sein sollte!

Spickzettel

Javas Ausnahmebehandlung (Exception Handling) basiert auf einer Klassenhierarchie, die in Throwable verwurzelt ist:

Throwable
├── Error          // Schwerwiegende Probleme (nicht abfangen)
└── Exception      // Behebbare Probleme
    └── RuntimeException  // Ungeprüfte Ausnahmen (Unchecked Exceptions)

Error repräsentiert schwerwiegende JVM-Probleme wie OutOfMemoryError oder StackOverflowError, die Anwendungen nicht behandeln sollten.

Exception unterteilt sich in geprüfte Ausnahmen (Checked Exceptions, direkte Unterklassen) und ungeprüfte Ausnahmen (Unchecked Exceptions, Unterklassen von RuntimeException):

Exception
├── IOException           // Datei-/Netzwerkprobleme
├── SQLException          // Datenbankprobleme
└── RuntimeException
    ├── NullPointerException
    ├── ArrayIndexOutOfBoundsException
    └── IllegalArgumentException

Das Abfangen eines übergeordneten Exception-Typs fängt auch alle dessen Unterklassen ab:

try {
    // Code
} catch (Exception e) {
    // Fängt ALLE Exceptions ab
}

try {
    // Code
} catch (RuntimeException e) {
    // Fängt nur RuntimeExceptions und deren Unterklassen ab
}

Verwenden Sie e.getClass().getSimpleName(), um den Klassennamen der Exception zu erhalten, und e.getMessage(), um deren Nachricht abzurufen.

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: "=== Specific Catch ===" ausgeben und ExceptionAnalyzer.analyzeSpecific(type) aufrufen
        
        // TODO: Eine Leerzeile ausgeben, dann "=== Parent Catch ===", dann ExceptionAnalyzer.analyzeWithParent() aufrufen
        
        // TODO: Eine Leerzeile ausgeben, dann "=== Grandparent Catch ===", dann ExceptionAnalyzer.analyzeWithGrandparent() aufrufen
    }
}
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