Checked vs. Unchecked Errors
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 61 von 87.
Sie haben gesehen, dass sich die Exception-Hierarchie von Java in verschiedene Zweige aufteilt. Der entscheidende Unterschied, den Sie verstehen müssen, besteht zwischen checked und unchecked Exceptions – dies beeinflusst, wie Sie diese in Ihrem Code behandeln müssen.
Geprüfte Exceptions sind Exceptions, die der Compiler dich zu behandeln zwingt. Sie erweitern Exception direkt (nicht über RuntimeException). Du musst sie entweder abfangen oder mit throws deklarieren:
// Muss IOException behandeln - es ist eine Checked Exception
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // Kann IOException auslösen
}
// Oder sie abfangen
public void readFileSafe(String path) {
try {
FileReader reader = new FileReader(path);
} catch (IOException e) {
System.out.println("File error: " + e.getMessage());
}
}Unchecked Exceptions erweitern RuntimeException. Der Compiler verlangt nicht, dass Sie diese behandeln – sie weisen in der Regel auf Programmierfehler wie Null-Referenzen oder ungültigen Array-Zugriff hin:
// Keine throws-Deklaration erforderlich
public int divide(int a, int b) {
return a / b; // Kann ArithmeticException auslösen (unchecked)
}
String name = null;
name.length(); // NullPointerException (unchecked)Wählen Sie beim Erstellen benutzerdefinierter Exceptions die Basisklasse basierend darauf aus, wie die Aufrufer damit umgehen sollen. Verwenden Sie Checked Exceptions für behebbare Bedingungen, die der Aufrufer vorhersehen sollte. Verwenden Sie Unchecked Exceptions für Programmierfehler, die in korrektem Code nicht auftreten sollten.
Aufgabe
EinfachLassen Sie uns ein Altersverifizierungssystem bauen, das den Hauptunterschied zwischen geprüften (checked) und ungeprüften (unchecked) Ausnahmen demonstriert! Sie werden benutzerdefinierte Ausnahmen beider Typen erstellen und sehen, wie der Compiler sie unterschiedlich behandelt.
Sie werden Ihren Code über vier Dateien organisieren:
InvalidAgeException.java: Erstellen Sie eine geprüfte Ausnahme (checked exception) für Fehler bei der Altersvalidierung. Diese Ausnahme sollte direktExceptionerweitern, was bedeutet, dass Aufrufer gezwungen sind, sie zu behandeln. Fügen Sie einen Konstruktor hinzu, der eine Nachricht akzeptiert und diese an die Elternklasse weitergibt.NegativeAgeException.java: Erstellen Sie eine ungeprüfte Ausnahme (unchecked exception) für den Fall, dass jemand ein negatives Alter angibt (ein Programmierfehler, der bei korrekter Eingabe nicht auftreten sollte). Diese sollteRuntimeExceptionerweitern. Fügen Sie einen Konstruktor hinzu, der eine Nachricht akzeptiert und an die Elternklasse weitergibt.AgeVerifier.java: Erstellen Sie eine Klasse, die Alter unter Verwendung beider Ausnahmetypen validiert. Fügen Sie zwei statische Methoden hinzu:verifyAge(int age)- Diese Methode sollte eineNegativeAgeException(ungeprüft) mit der Nachricht"Age cannot be negative: " + agewerfen, wenn das Alter kleiner als 0 ist. Wenn das Alter kleiner als 18 ist, werfen Sie eineInvalidAgeException(geprüft) mit der Nachricht"Must be 18 or older: " + age. Andernfalls geben Sie"Age " + age + " verified successfully"aus. Da diese Methode eine geprüfte Ausnahme wirft, müssen Sie sie mitthrows InvalidAgeExceptiondeklarieren.verifyAgeUncheckedOnly(int age)- Diese Methode verwendet nur ungeprüfte Ausnahmen. Wenn das Alter negativ ist, werfen Sie eineNegativeAgeExceptionmit demselben Nachrichtenformat. Wenn das Alter kleiner als 18 ist, werfen Sie eineIllegalArgumentExceptionmit der Nachricht"Too young: " + age. Andernfalls geben Sie"Age " + age + " verified (unchecked method)"aus. Beachten Sie, dass diese Methode keinethrows-Deklaration benötigt!Main.java: Führen Sie Ihr Verifizierungssystem zusammen! Sie erhalten eine Eingabe: ein Alter (Ganzzahl).Geben Sie zuerst
"=== Checked Exception Method ==="aus und rufen SieverifyAgemit dem eingegebenen Alter auf. Da sie eine geprüfte Ausnahme wirft, müssen Sie sie in einen try-catch-Block einschließen. Fangen SieInvalidAgeExceptionab und geben Sie"Checked exception caught: " + e.getMessage()aus. Fangen Sie auchNegativeAgeExceptionab und geben Sie"Unchecked exception caught: " + e.getMessage()aus.Geben Sie dann eine Leerzeile und
"=== Unchecked Exception Method ==="aus. Rufen SieverifyAgeUncheckedOnlymit demselben Alter auf. Obwohl diese Methode Ausnahmen werfen kann, sind Sie nicht gezwungen, sie abzufangen. Schließen Sie sie jedoch trotzdem in einen try-catch-Block ein, um Fehler elegant zu behandeln. Fangen SieNegativeAgeExceptionab und geben Sie"Runtime exception caught: " + e.getMessage()aus. Fangen SieIllegalArgumentExceptionab und geben Sie"Illegal argument caught: " + e.getMessage()aus.
Sie erhalten eine Eingabe: eine Ganzzahl, die das zu verifizierende Alter darstellt.
Beachten Sie den Hauptunterschied: Die Methode mit der geprüften Ausnahme erfordert eine throws-Deklaration und zwingt Aufrufer, sie zu behandeln, während die ungeprüfte Methode ohne jegliche Ausnahmebehandlung einwandfrei kompiliert. Dies ist die grundlegende Unterscheidung zwischen geprüften und ungeprüften Ausnahmen in Java!
Spickzettel
Java-Exceptions werden in geprüfte (checked) und ungeprüfte (unchecked) Exceptions unterteilt, was bestimmt, wie der Compiler deren Behandlung erzwingt.
Geprüfte Exceptions erweitern Exception direkt (nicht über RuntimeException). Der Compiler zwingt Sie dazu, diese entweder abzufangen oder mit throws zu deklarieren:
// Muss mit throws deklariert werden
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path);
}
// Oder abfangen
public void readFileSafe(String path) {
try {
FileReader reader = new FileReader(path);
} catch (IOException e) {
System.out.println("File error: " + e.getMessage());
}
}Ungeprüfte Exceptions erweitern RuntimeException. Der Compiler verlangt nicht, dass Sie diese behandeln. Sie weisen in der Regel auf Programmierfehler hin:
// Keine throws-Deklaration erforderlich
public int divide(int a, int b) {
return a / b; // Kann ArithmeticException auslösen (ungeprüft)
}
String name = null;
name.length(); // NullPointerException (ungeprüft)Wählen Sie beim Erstellen benutzerdefinierter Exceptions die Basisklasse basierend darauf aus, wie Aufrufer damit umgehen sollten:
- Verwenden Sie geprüfte Exceptions (erweitern
Exception) für behebbare Zustände, die der Aufrufer vorhersehen sollte - Verwenden Sie ungeprüfte Exceptions (erweitern
RuntimeException) für Programmierfehler, die in korrektem Code nicht auftreten sollten
Probier es selbst
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
// TODO: Teste die Methode für geprüfte Ausnahmen (Checked Exceptions)
// Drucke: "=== Checked Exception Method ==="
// Rufe AgeVerifier.verifyAge(age) in einem try-catch-Block auf
// - Catch InvalidAgeException: drucke "Checked exception caught: [message]"
// - Catch NegativeAgeException: drucke "Unchecked exception caught: [message]"
// TODO: Drucke eine Leerzeile, dann "=== Unchecked Exception Method ==="
// Rufe AgeVerifier.verifyAgeUncheckedOnly(age) in einem try-catch-Block auf
// - Catch NegativeAgeException: drucke "Runtime exception caught: [message]"
// - Catch IllegalArgumentException: drucke "Illegal argument caught: [message]"
}
}
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