Java und Exceptions

Willemers Informatik-Ecke

Fehler sind doof, aber beinahe unvermeidbar. Allerdings kann man unterscheiden zwischen Fehlern, die aufgrund von Schlamperei beim Programmieren entsteht und denen, die durch äußere Einwirkung entsteht.

Versuchen und Fangen

Die klassische Form, mit Fehlern umzugehen ist der Aufruf der Funktion und die Prüfung, ob der Rückgabewert signalisiert, dass alles geklappt hat. Dieses Verfahren wird durchaus auch in Java verwendet. Hinzu kommt aber die Ausnahmebehandlung. Der Grundansatz sieht so aus, dass ein Block von Anweisungen durch try eingekapselt wird. Wirft eine der aufgerufenen Funktionen eine Ausnahme, so wird diese durch den nachfolgenden catch-Befehl gefangen. Hier werden dann die notwendigen Maßnahmen ergriffen, um den Fehler zu bearbeiten.
try {
    // Anweisungen
} catch {Exception e) {
    // Fehlerfall
}
Der Parameter von catch ist eine Referenz auf eine Exception. Über diese können die Methoden getMessage oder toString aufgerufen werden. Beide liefern eine kurze Nachricht über die Ursache der Exception. Die Methode printStackTrace zeigt an, über welche Methodenaufrufe die Exception erreicht wurde und den Text, den getMessage liefert, also das, was die Exception auch liefert, wenn sie nicht gefangen wird.

Exception-Hierarchien

Exception erweitert die Klasse Throwable. Spezialisierte Ausnahmen erweitern die Klasse Exception. Die wichtigsten sind RuntimeException, die aus dem Programmlauf entsteht, und die Klasse IOException, die im Zusammenhang mit Dateien und Netzwerken hervorgerufen werden können. Die folgende Aufzählung zeigt exemplarisch Ableitungen von Exception:
  • RuntimeException (typischerweise durch Programmierfehler erzeugt)
    • NullPointerException
    • IllegalArgumentException
      • IllegalFormatException
      • InvalidKeyException
      • PatternSyntaxException
    • IndexOutOfBoundsException
    • NegativeArraySizeException
  • IOException
    • FileNotFoundException (Datei nicht gefunden)
    • EOFException (plötzliches Dateiende)
    • UnknownHostException (Remote Host nicht ansprechbar)
    • UnknownServiceException (Dienst nicht ansprechbar)
  • AWTException (durch das AWT ausgelöst)
  • ClassNotFoundException (durch das Laden von Klassen über ihren Namen)
  • TimeoutException (Time out von blockierenden Operationen)
Beim Abfangen des Fehlers müssen die Exceptions so gestaffelt werden, dass eine erweiterte Klasse zuerst gefangen wird. Je genauer eine Ausnahme beim Fangen präzisiert wird, desto präziser kann die Reaktion sein.

Das Fangen der RuntimeException gilt als schlechter Stil, weil damit pauschal die eigenen Programmierschlampereien verdeckt werden.

Eigene Exceptions

Eigene Exceptions erweitern die Klasse Exception oder eine ihrer Erweiterungen. In vielen Fällen müssen die eigenen Exceptions keine eigenen Attribute oder Methoden besitzen. Sie dienen dann nur der Unterscheidung von einer allgemeinen Exception.

Es ist sinnvoll, die Methode getMessage zu überschreiben. Sie liefert dann einen eigenen Text für die Ausnahmeursache.

Eine Methode kann eine Instanz einer Exception mit dem Befehl throw werfen. Sie muss, sofern es sich nicht um unchecked Exceptions wie beispielsweise der RuntimeException handelt, diesen Wurf im Methodenkopf ankündigen.

public void meineMethode throws MeineAusnahme {
    ...
    throw new MeineAusnahme();
    ...
}

Steht die Exception im Zusammenhang mit anderen Objekten, kann es sinnvoll sein, Konstruktoren zu bilden, die eine Referenz auf das auslösende Objekt als Parameter übernehmen.

class EigeneAusnahme extends Exception {
    MeinObjekt meinObjekt = null;
    public EigeneAusnahme() {
    }
    public EigeneAusnahme(MeinObjekt obj) {
        meinObjekt = obj;
    }
    MeinObjekt getMeinObjekt() {
        return meinObjekt;
    }
    @Override public String getMessage() {
        return "Dumme Sache passiert!";
    }
}
Ergänzend wurde hier noch getMessage überschrieben, damit eine Fehlermeldung erscheint.


Homepage - Java (C) Copyright 2012 Arnold Willemer