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
└── IllegalArgumentExceptionDa 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.
Aufgabe
EinfachLassen 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 eineNullPointerExceptionmit der Nachricht"Null value encountered" - Wenn der Typ
"index"ist, werfen Sie eineArrayIndexOutOfBoundsExceptionmit der Nachricht"Invalid index" - Wenn der Typ
"argument"ist, werfen Sie eineIllegalArgumentExceptionmit der Nachricht"Bad argument"
triggerArithmetic()- Werfen Sie eineArithmeticExceptionmit der Nachricht"Division error"triggerGeneric()- Werfen Sie eineRuntimeExceptionmit der Nachricht"Generic runtime error"- Wenn der Typ
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 SieExceptionThrower.triggerRuntime(type)innerhalb eines try-Blocks auf. Verwenden Sie separate catch-Blöcke fürNullPointerException,ArrayIndexOutOfBoundsExceptionundIllegalArgumentException. Geben Sie für jeden Block Folgendes aus:Caught specific: [exception class simple name]gefolgt vonMessage: [exception message]analyzeWithParent()- Rufen SieExceptionThrower.triggerArithmetic()innerhalb eines try-Blocks auf. Fangen Sie diese mitRuntimeException(dem Elterntyp) ab. Geben Sie aus:Caught via parent: RuntimeExceptiongefolgt vonActual type: [exception class simple name]analyzeWithGrandparent()- Rufen SieExceptionThrower.triggerGeneric()innerhalb eines try-Blocks auf. Fangen Sie diese mitException(noch höher in der Hierarchie) ab. Geben Sie aus:Caught via grandparent: Exceptiongefolgt vonActual 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 SieanalyzeSpecificmit Ihrer Eingabe auf.Geben Sie dann eine Leerzeile und
=== Parent Catch ===aus und rufen SieanalyzeWithParentauf.Geben Sie schließlich eine Leerzeile und
=== Grandparent Catch ===aus und rufen SieanalyzeWithGrandparentauf.
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
└── IllegalArgumentExceptionDas 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
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenFelder (Attribute)Konstruktor-MethodeKonstruktor-ÜberladungRückblick – Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (extends)Das super-SchlüsselwortMethoden überschreiben (@Override)Konstruktor-VerkettungDie Object-KlasseEinfache & mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenZusammenfassung - Mitarbeiter-Hierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-InterfaceZusammenfassung – Benutzerdefiniertes Sortieren10Ausnahmebehandlung in OOP
Exception-KlassenhierarchieBenutzerdefinierte ExceptionsChecked vs. Unchecked ErrorsTry-With-Resources-PatternRecap – Validierter Benutzer2Zugriffsmodifikatoren & Kapselung
Überblick über ZugriffsebenenGetter- und Setter-MethodenInformation HidingDas final-SchlüsselwortRückblick – Bankkonto-Manager5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenZusammenfassung – Formenrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, geschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Teil 1
Einführung in Design PatternsSingleton-PatternFactory-PatternBuilder-PatternObserver-PatternStrategy-Pattern14Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung3Klasseneigenschaften & Statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Zusammenfassung – Zähler & Utility6Interfaces & Abstrakte Klassen
Einführung in InterfacesInterfaces implementierenImplementierung mehrerer InterfacesDefault- & statische Methoden in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesZusammenfassung - Zahlungssystem