Konzept der Ausnahmebehandlung

Das Konzept der Ausnahmebehandlung wurde von der Programmierspache Ada in alle modernen Programmiersprachen übernommen. Eine Ausnahme ist eine Situation, die besonderer Behandlung bedarf. Es muss sich nicht direkt um einen Fehler handeln, sondern auch um eine Sondersituation, die einfach nicht der Regelfall ist. Das Auslösen einer Ausnahme nennt man: eine Ausnahme werfen.

Das Werfen einer Ausnahme bedeutet eine Unterbrechung des Programmablaufs. Ausnahmen können durch das Programm selbst geworfen werden oder durch das Laufzeitsystem. Ausnahmen können z.B. sein:

  • Division durch 0
  • Fehlende Netzwerkverbindung
  • Nicht geöffnete Datei
  • Nicht beschreibbare Datei
  • usw.

Die Möglichkeiten sind vielfältig. Auch die Definition eigener Ausnahmen ist möglich. Die Ausnahmen können an einer zentralen Stelle im Programm behandelt werden. Dort wird über eine angemessene Reaktion entschieden. Dabei sollen die Programmteile, die normalerweise ablaufen und solche, die Ausnahmen behandeln, klar voneinander getrennt sein.

So ist die Fehlerbehandlung auch unabhängig von der Benutzeroberfläche. Eine Funktion wirft einen Fehler und gibt diesen an die aufrufende Funktion weiter. Diese behandelt die Ausnahme oder gibt sie ebenfalls weiter. Die weitergebenden Funktionen kümmern sich nicht darum, wie die Ausnahmen behandelt werden.

Irgendwann erreichen die Ausnahmen bspw. die Klassen, welche die grafische Oberfläche darstellen. Diese reagieren nun z.B. mit einer Fehlermeldung auf die Ausnahme. Ob diese Meldung als Windows-Textbox erscheint oder als Meldung in einem Internetprogramm oder in einem Terminal, spielt für die Fachklasse, welche den Fehler ausgelöst hat, keine Rolle. Sie sagt nur, dass eine Ausnahme aufgetreten ist. Um die korrekte Behandlung kümmert sich die zuständige Klasse.

Eine Ausnahme wird in Form eines Objekts einer bestimmten Klasse geworfen. Behandelt wird sie in einer Ausnahmebehandlungsroutine, dem sog. exception handler.

Sprachelemente für die Fehlerbehandlung in Java

Dieser Abschnitt soll Ihnen einen Überblick über die Sprachelemente für die Fehlerbehandlung in der Programmiersprache Java geben. Ich beschreibe die Syntax und anschließend das Element selbst.Die Schlüsselwörter sind fett gedruckt.

throw Ausnahmeobjekt

Eine Ausnahmeobjekt wird geworfen. Die Programmsteuerung wird an die nächste zuständige Ausnahmebehandlung übergeben. Sollte keine Ausnahmebehandlung vorhanden sein, kommt es zum Abbruch des Programms.

try { Anweisungen}

Hier werden die Anweisungen zusammengefasst, für die eine Ausnahmebehandlung durchgeführt werden soll. Das bedeutet also so viel wie: "Versuche diese Anweisungen auszuführen, sei aber auf eine Ausnahme gefasst!"

catch (Ausnahmedeklaration) { Anweisungen}

Dieser Block fängt die Ausnahmen eines bestimmten Typs auf und behandelt sie. In den runden Klammern wird ein Objekt der zu fangenden Aufnahme deklariert. Für verschiedene Ausnahmen können verschiedene catch-Blöcke hintereinander folgen.

finally { Anweisungen }

Die Anweisungen in den catch-Blöcken werden nur ausgeführt, wenn eine Ausnahme des entsprechenden Typs aufgetreten ist. Das Programmfragment im finally-Block wird immer ausgeführt, gleichgültig, ob eine Ausnahme geworfen wurde oder nicht. Hier können Arbeiten durchgeführt werden, die immer durchgeführt werden müssen - auch im Fehlerfall, z.B. Schließen einer Datenbankverbindung oder einer Datei.

Ein try-Block muss immer entweder mit einem catch- oder einem finally-Block enden. catch darf dabei mehrmals vorkommen, wenn unterschiedliche Ausnahmen behandelt werden sollen, finally darf es pro try-Block nur einmal geben. Einen finally-Block muss es nicht geben.

Die Struktur einer try-Anweisung sehen Sie im Folgenden:

 try { // Anweisungen, die Ausnahmen auslösen könnten. //z.B. throw new Ausnahmetyp1; } catch (Ausnahmetyp1 a) { // Faengt Ausnahmen von Ausnahmetyp1 ab und behandelt sie. } catch (Ausnahmetyp2 a) { // Faengt Ausnahmen von Ausnahmetyp2 ab und behandelt sie. } finally { // Abschliessende Arbeiten, die immer durchgefuehrt werden. }

Mögliche Abläufe

Fall 1: Im try-Block wird keine Ausnahme ausgelöst

Die Anweisungen im try-Block werden ausgeführt und die catch-Blöcke werden ignoriert. Die Anweisungen in der finally-Klausel werden ausgeführt und das Programm wird hinter dem try-Block fortgesetzt.

Fal 2l: Im try-Block wird eine Ausnahme ausgelöst

Wenn eine Ausnahme geworfen wird (entweder ausgelöst durch die virtuelle Maschine oder durch eine throw-Anweisung) wird ein Objekt dieses Ausnahmetyps erzeugt. Die Verarbeitung des try-Blocks wird daraufhin abgebrochen. Die catch-Blöcke haben wie Methoden einen Übergabeparameter: das Ausnahmeobjekt. Der Typ dieses Parameters wird mit dem Typ des geworfenen Objekts verglichen.

Fall 2a: Es gibt eine passende Ausnahmebehandlung

Wenn der von einer Ausnahmebehandlung erwartete Parameter und das geworfene Objekt zueinander passen, wird die entsprechende Behandlung ausgeführt. Dabei wird die erste passende Fehlerbehandlung gestartet.  Wird innerhalb des catch-Blocks keine weitere Ausnahme geworfen, ist die Ausnahme behandelt.

Anschließend wird - sofern vorhanden - der finally-Block durchgeführt. Es wird nicht zu der Stelle zurückgesprungen, an welcher der Fehler aufgetreten ist, sondern die Verarbeitung läuft nach dem try-Block weiter.

Fall 2b: Es wird keine passende Ausnahmebehandlung gefunden

Wie vorher erwähnt, kann eine Ausnahme an die aufrufende Funktion weitergegeben werden. Das geschieht in diesem Fall. Ist eine finally-Klausel vorhanden, wird diese durchgeführt. Dann wird die Bearbeitung abgebrochen und die Kontrolle geht an den übergeordneten try-catch-Block über. Dieser muss nicht in einer übergeordneten Methode sein, sondern kann sich auch in derselben Methode befinden, da try-catch-Blöcke verschachtelt werden können.

Im übergeordneten Block wird nach einer passenden Ausnahmebehandlung gesucht. Wird keine gefunden, wird das Programm abgebrochen.

Die Ausnahmeklassen von Java

Alle Ausnahmen sind Unterklasse von java.lang.Throwable. Diese Klasse ist eine allgemeine Ausnahmeklasse, die eine Fehlermeldung speichern kann. Unterhalb von Throwable gibt es drei große Klassenhierarchien.

Die Klasse java.lang.Error ist die Oberklasse aller schwerwiegenden Fehler. Auslöser sind im Allgemeinen Probleme in der virtuellen Maschine. Sie sind so schwerwiegend, dass sie normalerweise nicht behandelt werden, sondern das Programm mit einer entsprechenden Fehlermeldung zum Absturz bringen sollten. Einzige Ausnahme ist die Klasse AssertionError, die eigentlich nicht in diese Kategorie fällt. Objekte der Klasse Error werden z.B. geworfen, wenn nicht genügend Speicher vorhanden ist.

Alle Ausnahmen, die nicht so schwerwiegend sind und eventuell für das Programm von Interesse sind, sind Unterklassen von java.lang.Exception. Diese Ausnahmen werden normalerweise abgefangen. Selbstgeschriebene Ausnahmen sind meistens Unterklassen von Exception.

Von der Klasse Exception ist die Klasse RuntimeException abgeleitet. Dabei handelt es sich um spezielle Ausnahmen des Laufzeitsystems wie z.B. wenn die Größe eines Arrays überschritten oder auf ein Objekt zugegriffen wird, für das kein Speicher reserviert ist.

Laden ...
Fehler!