Java Standard: Fehlerbehandlung


Bis hierher haben wir gesehen, wie ein lauffähiges Programm erstellt werden kann. Allerdings kann es noch fehlerhaft arbeiten, denn wichtige Routinen fehlen noch: die Mechanismen zum Abfangen von Fehlern.

Fehler können auf zwei Arten in ein Programm geraten: Zum Einen können die Benutzer des Programms fehlerhafte Eingaben machen. Wenn ein Benutzer an einer Eingabeaufforderung die Zeichenfolge "Zwölf" eingibt, das Programm aber die Zahl "12" erwartet, muss das Programm eine Möglichkeit haben, auf diesen Fehler reagieren zu können. Dafür gibt es natürlich verschiedene Möglichkeiten; so kann man zum Beispiel das Eingabefeld nur für Ziffern freigeben und alle anderen Zeichen ignorieren. Es gibt aber auch die Möglichkeit, dass das Programm erkennt, dass eine unerwartete Eingabe vorliegt und darauf reagieren. Für diesen Fall gibt es das Konstrukt Exceptions, zu deutsch: "Ausnahmen". Exceptions sind Meldungen, die der Interpreter auswirft, wenn das Programm einen Zustand erkennt, der eine eigens programmierte Bearbeitung benötigt. Das kann sich auf Eingaben durch einen Benutzer beziehen, aber auch interne Abläufe beinhalten. Zum Beispiel wird bei jedem Zugriff auf ein Array intern getestet, ob der Index innerhalb des zuvor festgelegten Bereiches liegt. Andernfalls wird eine spezielle Exception geworfen, die der Programmierer auswerten kann und das Programm dadurch geregelt auf diesen Fehler reagieren lassen kann. Wie Exceptions funktionieren wird im nächsten Kapitel im Detail erläutert. Exceptions werden seit der ersten Version Java 1.0 genutzt.

Die andere Form der Fehlerbehandlung bezieht sich auf die Programmierung selbst. Selbst wenn die Eingaben des Benutzers korrekt sind kann der Programmierer eine fehlerhafte Routine geschrieben haben. Solche logischen Fehler sind meist nur sehr schwer zu finden. Deswegen gibt es seit der Version Java 1.4 einen besonderen Testmodus, der sich Assertion (zu deutsch etwa: "Behauptung") nennt. Dabei wird das Schlüsselwort assert, gefolgt von einer logischen Behauptung (z.B. "x>0") und einem optionalen Fehlertext in den Code eingefügt. Dieser Test wird ausschließlich dann ausgeführt, wenn der Programmierer die Überprüfung seines Codes ausdrücklich beim Interpreter anfordert; während der normalen Ausführung wird der Code ignoriert und kostet dadurch keine zusätzliche Laufzeit. Dadurch können die Tests im Code verbleiben und bei späteren Änderungen wieder aktiviert werden. Die Programmierung solcher Tests wird im übernächsten Kapitel besprochen.

Die beiden Formen von Fehlerbehandlungen können also nach ihren Aufgaben getrennt werden: Um die Vorbedingungen (preconditions) für die saubere Ausführung einer Funktion oder Methode zu überprüfen werden Exceptions genutzt, für die Auswertung, ob die Routine eine sinnvolle Auswertung vorgenommen hat, kommen die Assertions in Anwendung (postconditions). Dabei ist es allerdings gelegentlich schwierig, eine sinnvolle Trennung vorzunehmen; ist beispielsweise eine private Routine, die ja nur innerhalb der Klasse sichtbar ist, Teil von preconditions? Oder gehört sie ausschließlich in die Tests auf postconditions? Derartige Trennungen muss der Programmierer im Einzelfall entscheiden.