Checked vs. Unchecked Errors
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 61 von 87.
Du hast gesehen, dass die exception-Hierarchie von Java in verschiedene Zweige aufgeteilt ist. Der entscheidende Unterschied, den du verstehen musst, besteht zwischen checked und ungeprüften exceptions. Dies beeinflusst, wie du sie in deinem Code behandeln musst.
Checked exceptions sind exceptions, die der Compiler dich zwingt zu handle. Sie erweitern Exception directly (nicht über RuntimeException). Du musst sie entweder catch oder mit throws declare:
// Muss IOException behandeln - es ist checked
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // Kann IOException werfen
}
// 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 du sie handle. Sie weisen typischerweise auf Programmierfehler wie Nullreferenzen oder ungültigen Array-Zugriff hin:
// Keine throws-Deklaration nötig
public int divide(int a, int b) {
return a / b; // Kann ArithmeticException werfen (unchecked)
}
String name = null;
name.length(); // NullPointerException (unchecked)Wenn du benutzerdefinierte exceptions erstellst, wähle die übergeordnete class danach aus, wie du möchtest, dass Aufrufer sie handle. Verwende checked exceptions für wiederherstellbare Bedingungen, die der Aufrufer erwarten sollte. Verwende unchecked exceptions für Programmierfehler, die in korrekt geschriebenem Code nicht auftreten sollten.
Aufgabe
EinfachErstellen wir ein Altersverifizierungssystem, das den wesentlichen Unterschied zwischen checked und unchecked exceptions demonstriert! Du erstellst benutzerdefinierte exceptions beider Typen und siehst, wie der Compiler sie unterschiedlich behandelt.
Du organisierst deinen Code auf vier Dateien verteilt:
InvalidAgeException.java: Erstelle eine checked exception für Fehler bei der Altersvalidierung. Diese exception sollte direktExceptionerweitern, was bedeutet, dass Callers gezwungen sein werden, sie zu behandeln. Füge einen constructor hinzu, der eine message akzeptiert und sie an die übergeordnete class weitergibt.NegativeAgeException.java: Erstelle eine unchecked exception für den Fall, dass jemand ein negatives Alter angibt (ein Programmierfehler, der bei korrekter Eingabe nicht auftreten sollte). Diese sollteRuntimeExceptionerweitern. Füge einen constructor hinzu, der eine message akzeptiert und weitergibt.AgeVerifier.java: Erstelle eine class, die Alter mithilfe beider exception-Typen validiert. Füge zwei statische Methoden hinzu:verifyAge(int age)– Diese Methode sollteNegativeAgeException(unchecked) mit der message"Age cannot be negative: [age]"auslösen, wenn das Alter kleiner als 0 ist. Wenn das Alter kleiner als 18 ist, löseInvalidAgeException(checked) mit der message"Must be 18 or older: [age]"aus. Andernfalls gibAge [age] verified successfullyaus. Da diese Methode eine checked exception auslöst, musst du sie mitthrows InvalidAgeExceptiondeklarieren.verifyAgeUncheckedOnly(int age)– Diese Methode verwendet ausschließlich unchecked exceptions. Wenn das Alter negativ ist, löseNegativeAgeExceptionmit demselben Nachrichtenformat aus. Wenn das Alter kleiner als 18 ist, löse eineIllegalArgumentExceptionmit der message"Too young: [age]"aus. Andernfalls gibAge [age] verified (unchecked method)aus. Beachte, dass diese Methode keinethrows-Deklaration benötigt!Main.java: Führe dein Verifizierungssystem zusammen! Du erhältst eine Eingabe: ein Alter (Ganzzahl).Gib zuerst
=== Checked Exception Method ===aus und rufeverifyAgemit dem eingegebenen Alter auf. Da die Methode eine checked exception auslöst, musst du den Aufruf in einen try-catch-Block einschließen. FangeInvalidAgeExceptionab und gibChecked exception caught: [message]aus. Fange außerdemNegativeAgeExceptionab und gibUnchecked exception caught: [message]aus.Gib anschließend eine leere Zeile und
=== Unchecked Exception Method ===aus. RufeverifyAgeUncheckedOnlymit demselben Alter auf. Obwohl diese Methode exceptions auslösen kann, bist du nicht gezwungen, sie abzufangen. Schließe sie trotzdem in einen try-catch-Block ein, um Fehler ordnungsgemäß zu behandeln. FangeNegativeAgeExceptionab und gibRuntime exception caught: [message]aus. FangeIllegalArgumentExceptionab und gibIllegal argument caught: [message]aus.
Du erhältst eine Eingabe: eine Ganzzahl, die das zu verifizierende Alter darstellt.
Beachte den wesentlichen Unterschied: Die Methode mit der checked exception erfordert eine throws-Deklaration und zwingt Callers, sie zu behandeln, während die unchecked-Methode ohne jegliche exception-Behandlung problemlos kompiliert. Dies ist der grundlegende Unterschied zwischen checked und unchecked exceptions in Java!
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: Test the checked exception method
// Print: "=== Checked Exception Method ==="
// Rufe AgeVerifier.verifyAge(age) in einem try-catch auf
// - Catch InvalidAgeException: print "Checked exception caught: [message]"
// - Catch NegativeAgeException: print "Unchecked exception caught: [message]"
// TODO: Print a blank line, then "=== Unchecked Exception Method ==="
// Rufe AgeVerifier.verifyAgeUncheckedOnly(age) in einem try-catch auf
// - Catch NegativeAgeException: print "Runtime exception caught: [message]"
// - Catch IllegalArgumentException: print "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Übe selbstständig: Online-Java-Compiler