Java Programmierung mit Exceptions > Fehlerbehandlung in Java Mark Egloff 2006 1 Java Programmierung mit Lernziel Heute Abend > Sie lernen die Bedeutung von Exceptions kennen > Sie wissen wie Laufzeitfehler in Java erzeugt und gehandhabt werden > Sie können gezielt eigene Fehlerbehandlungen implementieren Mark Egloff 2006 2 Java Programmierung mit Exceptions „Wir sind in Sicherheit! Er kann uns nicht erreichen! – Sicher? – Ganz sicher! Bären haben Angst vor Treibsand!“ Häger, Dik Browne Mark Egloff 2006 3 Java Programmierung mit Exceptions Was ist eine „Exception“ ? > Exceptions bedeutet übersetzt Laufzeitfehler oder Ausnahmesituation. Darunter werden Fehler verstanden, welche erst bei der Ausführung des Programms auftreten > Viele Laufzeitfehler lassen sich auf Programmierfehler zurückführen z.B. NullPointerException, die aber unter Umständen nur bei seltenen Situationen stattfinden. Die Gründe können manchmal sehr komplex sein > Es gibt auch Laufzeitfehler die nicht unbedingt auf „schlechte“ Programmierung zurückzuführen sind z.B. Datei auf CD-ROM abspeichern Der Benützer wählte das falsche Laufwerk. > All diese Laufzeitfehler müssen von unseren Programmen erkannt und behandelt werden, ansonsten würde das Programm einfach „abstürzen“ > Java bietet eine elegante Methode, um mit Fehlern flexibel umzugehen Mark Egloff 2006 4 Java Programmierung mit Excpetions Unterschiede Compiler- Fehler vs. Laufzeitfehler > Fehler können anhand des Zeitpunkts ihres Auftretens unterschieden werden: Fehler treten schon bei der Übersetzung oder erst zur Laufzeit auf. > Sicherlich sind Fehler, die der Compiler entdeckt, die angenehmeren. Man kann sie analysieren und den Code entsprechend anpassen. > Im ungünstigeren Fall treten Laufzeitfehler erst beim Anwender – dem Kunden – auf und beenden das Programm ohne geeignete Behandlung, lassen es »abstürzen«. > Die Behandlung der Laufzeitfehler macht bei interaktiven Programmen häufig den Hauptteil des Codes aus. Die produktiven Programmteile sind mit unzähligen Kontrollanweisungen durchsetzt, die auf Umweltsituationen reagieren müssen Konfigurationsmanagement > Laufzeitfehler werden daher häufig ignoriert! da Aufwendig Mark Egloff 2006 5 Java Programmierung mit Excpetions Typische Laufzeitfehler > Hier sind einige Laufzeitfehler aufgelistet, die wohl am häufigsten Programme zum Absturz bringen: > NullPointerException: Zugriff über eine Referenz auf eine Objekteigenschaft. Die Referenz zeigt aber auf kein Objekt sondern ist NULL > ArrayIndexOutOfBoundsException: Zugriff auf Arrayfelder ausserhalb der Arraygrenzen > IllegalArgumentException: Ungültiger Parameterwert wurde übergeben > ArithmeticException: Division durch 0 Mark Egloff 2006 6 Java Programmierung mit Excpetions Beispiel eines „unerwarteten“ Laufzeitfehler (1/3) > In den abgegeben Dateien Finden Sie eine Applikation, die „manchmal“ einen Fehler auslöst. Die Applikation ist schon bekannt der DES Verschlüsseler von Lektion 06 > Öffnen Sie nun das vorbereitete Projekt in Eclipse: 1. Lektion11.zip Datei vom Email entpacken und in einen Ordner ablegen 2. Eclipse starten 3. Projekt importieren mittels Menu „File > Import“ 4. Aus dem Import Wizard „General > Existing Project into Workspace“ wählen 5. Den Ordner „Lektion 11\Example“ aus der entpackten Zip Datei wählen > Starten Sie „RunVerschluesselung“. Die Applikation liest ein String ein und verschlüsselt es mit dem „DES“ Algorithmus. Experimentieren Sie mit unterschiedlichen Text längen 5-10 Zeichen. Was Stellen Sie fest? Mark Egloff 2006 7 Java Programmierung mit Excpetions Beispiel eines „unerwarteten“ Laufzeitfehler (2/3) > Die Applikation löst bei einer bestimmten String Längen (x % 8 == 0) einen Fehler aus und bricht das Programm aus. Das wäre ärgerlich wäre es beim Testen nicht aufgefallen Ablauf des Programmes „RunVerschluesselung“ Bitte geben sie den Text für eine Verschlüsselung ein: Java ist einfach DES verschlüsselung:16 ’d}¾Öíb=«^fŸåbHˆ?¥J• Exception in thread "main" java.lang.RuntimeException: javax.crypto.BadPaddingException: Given final block not properly padded at DESVerschluessler.decrypt(DESVerschluessler.java:61) at RunVerschluesselung.main(RunVerschluesselung.java:20) Mark Egloff 2006 8 Java Programmierung mit Excpetions Beispiel eines „unerwarteten“ Laufzeitfehler (3/3) > Noch ärgerlicher, wir „haben“ den SourceCode nicht zur Verfügung dort wo der Fehler auftritt (DESVerschluessler.java:61). Somit bleibt uns nur noch die Möglichkeit übrig den Fehler abzufangen und zu behandeln. > Hierzu verwenden wir die „try/catch“ Möglichkeit. Hängen Sie unten an den bestehenden „catch“ Block in „main()“ folgenden Code an und wiederholen Sie die Fehlerauslösung, beobachten Sie nun das Resultat. catch(RuntimeException rt){ System.out.println("unerwarterter Fehler:" + rt); } > Der Fehler tritt nun immer noch auf, aber wir haben nun die Möglichkeit an dieser Stelle zu reagieren z.B. eine Behandlung oder gar Wiederholung durchzuführen. Mark Egloff 2006 9 Java Programmierung mit Exceptions Früheres Konzept der Fehlerbehandlungen > Viele ältere Sprachen z.B. VB, C, Perl besitzen kein spezielles Konzept für die Fehlerbehandlung > Es wurde oft der Rückgabewert einer Methode verwendet, um einen Fehlschlag anzuzeigen. Der Fehlercode war häufig einfach –1, aber auch NULL oder 0. Ein Standard gab es nicht > Ein Folge-Problem stellte dann Wartbarkeit des Programms dar. Der Programmfluss wird durch Abfragen der Funktionsergebnisse unangenehm unterbrochen. Häufig entstehen mit den Fehlerabfragen kaskadierte if-Abfragen, die den Quellcode schwer lesbar machen. Die Fehlerbehandlung erfolgte dann nicht zentral sondern war an mehreren Stellen im Code verteilt. > Ein neues Konzept musste deshalb dringend her Mark Egloff 2006 10 Java Programmierung mit Exceptions Früheres Konzept der Fehlerbehandlungen z.B.: Problem negativer Radius bei Klasse „Kreis“ Kreis k = new Kreis(-3.5f); System.out.println( k.berechneUmfang() ); negativ z.B. Methode mit Rückgabewert um Fehler zu signalisieren public float berechneUmfang() { if (this.radius < 0) return -1; else return this.radius * 2 * PI; } z.B. Fehlerbehandlung anhand des Rückgabewertes if (k.berechneUmfang() == -1 ) System.err.println("Fehler aufgetreten!"); Mark Egloff 2006 11 Java Programmierung mit Exceptions Das neue Konzept: „Try“ und „Catch“ > Das neue Konzept heisst „Try“ und „Catch“ und es wurde in die neueren Sprachen (z.B. C++, Java, C#, Javascript, PHP) gerade als grundlegender Syntax eingebettet > Bei der Verwendung dieses Konzeptes wird der Programmfluss nicht unterbrochen, sondern ein besonders ausgezeichnetes Programmstück wird bezüglich auftretender Fehler überwacht und gegebenenfalls spezieller Code zur Behandlung solcher Fehler aufgerufen. Mark Egloff 2006 12 Java Programmierung mit Exceptions Das neue Konzept: „Try“ und „Catch“ > Ein überwachter Programmbereich (Block) wird mit dem Schlüsselwort „try“ eingeleitet und mit „catch“ beendet. Hinter „catch“ folgt der Programmblock, der beim Auftreten eines Fehlers ausgeführt wird, um den Fehler abzufangen oder zu behandeln. > Anstelle eines Fehlercodes wird im Falle eines Fehlers ein Exceptionobjekt erzeugt, dass alle Angaben des Fehlers beinhaltet. Dieses wird an die Behandlungsroutine weitergeleitet. > Um Fehlerbehandlungen zu erzwingen, überwacht der Compiler, dass alle möglichen, auftretenden Fehler mittels „try“ und „catch“ in einer Applikation behandelt werden. Wird dies nicht gemacht, treten entsprechende Compilerfehler auf. Somit müssen Programmierer eine Behandlung implementieren Mark Egloff 2006 13 Java Programmierung mit Exceptions Das neue Konzept: „Try“ und „Catch“ Beispiel 1: Einfache Methode mit „try“ und „catch“ Block public void setRadius(float radius) { try { if ( radius < 0) throw new Exception("radius < 0!"); else this.radius = radius; } catch( Exception ex){ Fehlerauslösung System.err.println(ex); } } Fehlerbehandlung Mark Egloff 2006 14 Java Programmierung mit Excpetions Mark Egloff 2006 15 Java Programmierung mit Exceptions Das neue Konzept: „Try“ und „Catch“ Der Programmfluss bei einer einfachen Exception try { Try Block Foo f = x.doRiskyThing() Fehler } catch(Exception ex) { y.handleError(ex); Catch Block } Ablauf im Normalfall Ablauf im Fehlerfall Mark Egloff 2006 16 Java Programmierung mit Exceptions Syntax Regeln für „Try“ try { ... } > Mit „try“ leiten wir einen Block ein indem mögliche Exceptions auftreten können > Nach dem Schlüsselwort „try“ folgt immer ein Block mit „{}“ Klammern > Nach dem „try“- Block muss mindestens ein „catch“- oder ein „finally“- Block folgen. Mark Egloff 2006 17 Java Programmierung mit Exceptions Syntax Regeln für „Catch“ catch(Exception ex) { ... } > Mit „catch“ leiten wir einen Block ein indem geworfene Exceptions aufgefangen und behandelt werden können > Nach dem Schlüsselwort „catch“ folgt eine Parameterübergabe. Dort wird ein „Exception“ - Objekt an den Behandlungsblock übergeben. Es muss der Typ und Namen des Parameters angegeben werden. Es wird nur ein Parameter unterstützt und er muss vom Typ „Throwable“ sein > Nach der Parameterübergabe folgt der Implementationsblock mit „{}“ Klammern > Es dürfen mehrere „catch“-Blöcke nach einem „try“-Block folgen, jedoch muss jeder „catch“ Block einen anderen Parametertyp aufweisen, ähnliche Regel wie beim Überladen der Methoden. Mark Egloff 2006 18 Java Programmierung mit Exceptions Wie weiss ich wann welche Fehler auftreten können? Beispiel 2: Ermittlung und implementation einer Fehlerbenhandlung > Wir wollen eine Datei mit Hilfe der Klasse „java.io.RandomAccessFile“ zeilenweise auslesen. Hierzu betrachten wir kurz das JavaDoc der Klasse > Aus der API-Dokumentation geht hervor, dass der Konstruktor von „RandomAccessFile“ eine „FileNotFound“ Exception-Ausnahme auslösen kann. > Mithilfe der Funktion „readLine()“ lesen wir so lange Zeilen ein, bis die Datei ausgeschöpft ist. Die Methode „readLine()“ kann eine „IOException“ auslösen. > Wir müssen diese Exceptions behandeln und setzen daher die Problemzonen in einen try- und catch-Block. Mark Egloff 2006 19 Java Programmierung mit Exceptions Wie weiss ich wann welche Fehler auftreten können? Beispiel 2: Ermittlung und implementation einer Fehlerbenhandlung Auschnitt aus dem JavaDoc der Klasse „java.io.RandomAccessFile“ Mark Egloff 2006 20 Java Programmierung mit Exceptions Wie weiss ich wann welche Fehler auftreten können? Beispiel 2: Ermittlung und implementation einer Fehlerbenhandlung import java.io.*; public class ReadFileWithRAF { public static void main( String[] args ) { try { RandomAccessFile f; f = new RandomAccessFile( "EastOfJava.txt", "r" ); for ( String line; (line=f.readLine()) != null; ) System.out.println( line ); } catch ( FileNotFoundException e ) { System.err.println( "Datei gibt’s nicht!" ); } catch ( IOException e ){ System.err.println( "Schreib- Leseprobleme!" ); } } } Mark Egloff 2006 21 Java Programmierung mit Exceptions Das neue Konzept: „Try“ und „Catch“ Wiederholung kritischer Bereiche > Es gibt in Java bisher keine Möglichkeit bei Exceptions, an den Punkt zurückzukehren, der den Fehler ausgelöst hat. Das ist aber oft erwünscht, z.B. wenn eine fehlerhafte Eingabe zu wiederholen ist. > Um dieses Problem zu lösen muss die Behandlung des Fehlers innerhalb der Wiederholung bzw. Schleife erfolgen. > Hierbei ist natürlich Vorsicht geboten, da dies schnell zu Endlosschleifen führen kann. Sofern möglich, sollten solche Konstrukte vermieden werden Mark Egloff 2006 22 Java Programmierung mit Exceptions Das neue Konzept: „Try“ und „Catch“ Wiederholung kritischer Bereiche z.B. Wiederholung einer Eingabe int number = 0; while ( true ) { try { System.out.print( "Bitte Zahl eingeben" ); number = Integer.parseInt( s ); break; } catch ( NumberFormatException e ) { System.out.println( "Das war keine Zahl!" ); } } Mark Egloff 2006 23 Java Programmierung mit Exceptions Fehler weiterleiten, die Anweisung „throws“ Es ist nicht immer sinnvoll jeden Fehler gerade an der Stelle zu behandeln wo er aufgetreten ist. Dies würde in eine Unmenge von „try“ und „catch“ Blöcken enden, welches die Wartbarkeit des Codes erschweren würde. > Es gibt daher die Möglichkeit anstelle den Fehler direkt mit „catch“ abzufangen diesen einfach an die nächst höhere Methode im Stack weiterzureichen. Dies erlaubt es später die Fehlerbehandlungen zu zentralisieren und somit zu vereinfachen. StackTrace > MyApp.main(args) MyApp.eingabe() Kreis.setRadius(r) Mark Egloff 2006 Fehler 24 Java Programmierung mit Exceptions Fehler weiterleiten, die Anweisung „throws“ > Diese Weiterleitung wird mit einen Anweisung „throws“ erreicht. Diese muss bei der Methodendeklaration nach der Parameterübergabe angegeben werden. Falls mehrere Arten von Exceptions ausgelöst werden, müssen diese einfach mittels Kommas getrennt aufgelistet werden z.B. Weiterleitung einer Exception class Kreis { ... public void setRadius(float radius) throws Exception { if ( radius < 0) throw new Exception("radius < 0!"); else this.radius = radius; } } Mark Egloff 2006 25 Java Programmierung mit Exceptions Fehler weiterleiten, die Anweisung „throws“ > Mittels der Weiterleitung „bubbelt“ der Fehler entlang nach oben und kann dann irgendwann abgefangen werden z.B. Weiterleitung und Abfangen der Exception in „main()“ class MyApp { public static void main(String args[]) { try { Kreis k = eingabe(); Fehler } catch(Exception ex) { System.err.println(ex); } } } Mark Egloff 2006 26 Java Programmierung mit Exceptions Fehler weiterleiten, die Anweisung „throws“ > Ist die Fehlerbehandlung in einer Applikation ganz „egal“, können wir alle Fehler an die JVM weiterleiten, die dann das Programm im Fehlerfall abbricht. > Hierbei muss lediglich die „throws“ Anweisung bei der Methodendeklaration von „main()“ angewendet werden z.B. Weiterleitung der Exception an die JVM class MyApp { public static void main(String args[]) throws Exception { ... } } Mark Egloff 2006 27 Java Programmierung mit Exceptions Abschliessende Arbeiten mit „finally“ > Es gibt Fälle wobei immer abschliessende Arbeiten getätigt werden müssen. Diese sind unabhängig von den zuvor aufgetretenen Fehlern z.B. die Freigabe von Ressourcen schliessen von Dateien. Diese müssen immer ausgeführt werden > Hierzu wurde im Konzept ein zusätzlicher Block vorgesehen Nach einem (oder mehreren) catch kann deshalb optional ein „finally“Block folgen. > Die Anweisungen im „finally“-Block werden immer ausgeführt, auch wenn in „try“ und „catch“ ein „return“, „break“ oder „continue“ steht. Das bedeutet, der „finally“ Block wird in jedem Fall ausgeführt. Mark Egloff 2006 28 Java Programmierung mit Exceptions Abschliessende Arbeiten mit „finally“ Der Programmfluss bei „finally“ Try Block try { Foo f = x.doRiskyThing() } Catch Block catch(Exception ex) {...} Finally Block finally { closeResources(); } Mark Egloff 2006 Fehler Ablauf im Normalfall Ablauf im Fehlerfall 29 Java Programmierung mit Exceptions Abschliessende Arbeiten mit „finally“ Beispiel: Freigabe der Ressource im „finally“ Block import java.io.*; public class ReadFileWithRAF { public static void main( String[] args ) { try { RandomAccessFile f; f = new RandomAccessFile( "EastOfJava.txt", "r" ); for ( String line; (line=f.readLine()) != null; ) System.out.println( line ); } catch ( FileNotFoundException e ) {...} catch ( IOException e ){...} Dummerweise kann „close()“ ebenfalls finally { eine Exception auslösen if ( f != null ) try { f.close(); } catch ( IOException e ) { e.printStackTrace(); } } } } Mark Egloff 2006 30 Java Programmierung mit Exceptions Syntax Regeln für „finally“ finally { ... } > Mit „finally“ leiten wir einen Block ein, der in jedem Fall abgearbeitet wird. Er ist daher ideal um abschliessende Arbeiten zu tätigen > Der „finally“ Block ist im Zusammenhang mit „try“ und „catch“ optional. Jedoch kann „finally“ nicht alleine für sich stehen. Er muss immer nach einem „try“ Block folgen. > Nach dem Schlüsselwort „finally“ folgt der Implementationsblock mit „{}“ Klammern > Es darf pro „try“ Block nur ein „finally“ Block implementiert werden Mark Egloff 2006 31 Java Programmierung mit Exceptions Abschliessende Arbeiten mit „finally“ Beispiel: „try“ und „finally“ ohne „catch“ Block public class NoCatchBecauseOfFinallyBlock { static void buh() { try { throw new ArithmeticException( "Keine Lust zu rechnen" ); } finally { System.out.println( "Mach noch was zum Schluss!" ) } } public static void main( String[] args ) { buh(); } } Mark Egloff 2006 32 Java Programmierung mit Exceptions Abschliessende Arbeiten mit „finally“ Beispiel: Keine Exceptionweiterleitung public class NoExceptionBecauseOfFinallyReturn { static void buh() { try { throw new ArithmeticException( "Keine Lust zu rechnen" ); } finally { Dummerweise wird die Methode vorher verlassen return; bevor die Weiterleitung der Exception erfolgen } kann! } public static void main( String[] args ) { buh(); } } Mark Egloff 2006 33 Java Programmierung mit Exceptions Exceptions sind Objekte Erzeugung und Handhabung von Exceptions > Tritt ein Fehler auf, so wird ein so genanntes Exception-Objekt erzeugt. Diese wird dann an den nächsten, entsprechenden „catch“ Block als Parameter übergeben. > Dieses Objekt ist ein ganz normales Java Objekt und stammt von einer Klasse „java.lang.Throwable“ ab (Basisklasse aller Exceptions). Es werden somit alle nötigen Angaben des Fehlers in ein Objekt gepackt und stehen dann bei der Behandlung zur Verfügung > Eine Exception wird zuerst mittels dem „new“ Operator und dem Konstruktoraufruf der Klasse instanziert. Danach wird es mit der Anweisung „throw“ geworfen bzw. als Fehler ausgelöst Mark Egloff 2006 34 Java Programmierung mit Exceptions Exceptions sind Objekte Erzeugung und Handhabung von Exceptions z.B. Erstellung und Auslösung einer Exception public void setRadius(float radius) { if ( radius < 0) throw new IllegalArgumentException("radius < 0!"); } 1. Exception-Klasse muss vom Typ „Throwable“ abgeleitet sein 2. Exception-Objekt instanzieren 3. Exception-Objekt mittels „throw“ werfen Mark Egloff 2006 35 Java Programmierung mit Exceptions Exceptions sind Objekte Erzeugung und Handhabung von Exceptions > Wichtige Eigenschaften eines Exception-Objektes sind: > „getClass()“: die Klasse selber gibt den Typ der Exception an > „getMessage()“:Fehlermeldung (falls nötig in mehreren Sprachen) > „printStackTrace()“: Ausgabe des Stacktrace (Angabe in welcher Klasse, Methode und bei welcher Linie des SourceCodes der Fehler ausgelöst wurde) > „getCause()“: Ursprünglicher Fehler (falls dies nur ein Folgefehler bzw. eine Weiterleitung war) z.B. Zugriff auf Eigenschaften des Exception-Objektes bei der Behandlung catch(IllegalArgumentException ex){ System.err.println( ex.getMessage() ); ex.printStackTrace(); } Mark Egloff 2006 36 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions > Das Java API besitzt eine grosse Menge an unterschiedlichen ExceptionKlassen ca.750 Klassen. > Bei einer solchen grossen Menge an verschiedenartiger Fehler wäre der Programmierer überfordert für jede einzelne mögliche Exception eine entsprechende Behandlungsroutine zu implementieren > Um diese Handhabung zu vereinfachen wurde die Hierarchie bei der Behandlung der Exceptions berücksichtigt. Diese erlaubt es, Fehler generisch handzuhaben. > Als Grundlage für dieses Hierarchie-Konzept wird die Vererbung und das Überladen von Methoden bzw. von „catch“ Blöcken verwendet Mark Egloff 2006 37 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions > Eine Exception ist ein Objekt, welches direkt oder indirekt von „java.lang.Throwable“ abgeleitet ist. > Von dort aus verzweigt sich die Vererbungshierarchie der Exception-Arten nach „java.lang.Exception“ und „java.lang.Error“. > Die Klassen, die aus „Error“ hervorgehen, müssen nicht weiterverfolgt werden. Es handelt sich hierbei um Fehler, die so schwerwiegend sind, dass sie zur Beendigung des Programms führen und vom Programmierer nicht weiter beachtet werden müssen. Mark Egloff 2006 38 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions Mark Egloff 2006 39 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions Mark Egloff 2006 40 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions > Alle Exceptions können vom Typ der Basisklasse und somit auch als „Throwable“ gehandhabt werden. z.B. Austauschbarkeit bei Objekten, dies gilt auch bei Exceptions Throwable t = new FileNotFoundException(); Exception e = new FileNotFoundException(); IOException ioe = new FileNotFoundException(); FilenotFoundException fnfe = new FileNotFoundException(); Throwable Exception IOException FileNotFoundException Mark Egloff 2006 41 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions > Dieses Prinzip erlaubt uns zu entscheiden nach welcher Priorität wir die Exceptions handhaben möchten. z.B. können wir gewisse Exceptions generisch oder andere explizit abhandeln > Wenn zum Beispiel eine „FileNotFoundException“ auftritt, dann ist diese Klasse von „IOException“ abgeleitet. Wenn wir alle „IOException“ auffangen, behandeln wir damit auch gleichzeitig die „FileNotFoundException“ mit > Besitzt ein „try“ Block mehrere „catch“ Blöcke so wird jeweils der „catch“ Block genommen bei dem der Parameterdatentyp mit dem jeweiligen Exception-Objekt am nächsten verwand ist Mark Egloff 2006 42 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions Beispiel: „FileNotFoundException“ als „IOException“ handhaben RandomAccessFile f = null; try { f = new RandomAccessFile( "d:/file.txt, "r" ); Fehler for ( String line; (line = f.readLine()) != null; ) System.out.println( line ); } catch ( IOException e ) { System.err.println( "Ein/Ausgabe-Probleme." ); Throwable } Exception IOException FileNotFoundException Mark Egloff 2006 43 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions Beispiel: „IOException“ als „Exception“ handhaben RandomAccessFile f = null; try { f = new RandomAccessFile( "d:/file.txt, "r" ); for ( String line; (line = f.readLine()) != null; ) System.out.println( line ); } Fehler catch ( FileNotFoundException e ) {...} catch ( Exception e ) {...} Throwable catch ( Throwable t ) {...} Exception IOException FileNotFoundException Mark Egloff 2006 44 Java Programmierung mit Exceptions Arten und Hirarchie von Exceptions > Um alle Arten von Fehlern abzufangen können die Exceptions jeweils weitergeleitet werden und in „main()“ als Typ „Throwable“ behandelt werden z.B. Generische Handhabung von Exceptions class MyApp { public static void main(String args[]) { try { ... } catch( Throwable t ) { System.err.println(t); } } } Mark Egloff 2006 45 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions RuntimeExceptions > Einige Fehlerarten können potenziell an vielen Programmstellen auftreten, etwa eine Division durch 0 oder ungültige Indexwerte beim Zugriff auf Array-Elemente. > Treten solche Fehler beim Programmlauf auf, liegt in der Regel ein Denkfehler des Programmierers vor, und das Programm sollte normalerweise nicht versuchen, die ausgelöste Ausnahme aufzufangen und zu behandeln. > Daher wurde die Unterklasse „RuntimeException“ eingeführt, die Fehler beschreibt, die vom Programmierer behandelt werden können, aber nicht müssen. Mark Egloff 2006 46 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions RuntimeExceptions Mark Egloff 2006 47 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions Harte Fehler: Errors > Fehler, die von der Klasse „java.lang.Error“ abgeleitet sind, stellen Fehler dar, die mit der JVM in Verbindung stehen. > Beispiele für konkrete Error-Klassen sind AnnotationFormatError, AssertionError, AWTError, CoderMalfunctionError, FactoryConfigurationError, LinkageError, ThreadDeath, TransformerFactoryConfigurationError, VirtualMachineError (mit den Unterklassen InternalError, OutOfMemoryError, StackOver-flowError, UnknownError). > Da solche Fehler „abnormales“ Verhalten anzeigen, müssen sie auch nicht mit einem „try/catch“-Block aufgefangen werden oder mit „throws“ weiter nach oben geleitet werden. Mark Egloff 2006 48 Java Programmierung mit Exceptions Arten und Hierarchie von Exceptions Unchecked Exceptions > „RunTimeExceptions“ und „Error“ werden nicht vom Compiler überwacht. Man spricht auch in solchen Fällen von „Unchecked Exceptions“ Mark Egloff 2006 49 Java Programmierung mit Exceptions Eigene Exception Klassen definieren > Bevor man eigene Exceptionklassen entwirft, sollte man sich erst überlegen was für eine Art von Fehler es ist und wie er behandelt werden sollte. Hierbei sind folgende Denkschritte hilfreich: 1. 2. Beschreibt wirklich keine bestehende Exception Klasse des Java API diese Ausnahme? JavaDoc ansehen, mit Google nach Hinweisen suchen > Ja > Nein Eigene Exceptionklasse implementieren Bestehende Klassen verwenden oder von Ihr ableiten Suchen der geeigneten Basis-ExceptionKlasse: Muss der Programmierer diese zwingend behandeln? > Ja > Nein „Error“ oder „RuntimeException“ als Basisklasse nehmen „Throwable“ oder „Exception“ als Basisklasse nehmen Mark Egloff 2006 50 Java Programmierung mit Exceptions Eigene Exception Klassen definieren > Eigene Exceptions sind direkte oder indirekte Unterklassen von Exception. Sie implementieren oft zwei Konstruktoren: einen Standard-Konstruktor und einen mit einem String parametrisierten Konstruktor. z.B. Eigene Exception-Klasse implementieren public class IllegalSchokoColorException extends IllegalArgumentException { public IllegalSchokoColorException() { super(); } public IllegalSchokoColorException( String s ) { super( s ); } } Mark Egloff 2006 51 Java Programmierung mit Exceptions Eigene Exception Klassen definieren z.B. Eigene Exception-Klasse werfen class Schokolade { String f; public Schokolade(String f) { this.f = f; } public test() throws IllegalSchokoColorException { if (...) throw new IllegalSchokoColorException( "Diese Schokoladen-Farbe gibt es nicht:" + f); } Mark Egloff 2006 52 Java Programmierung mit Exceptions Eigene Exception Klassen definieren z.B. Eigene Exception-Klasse werfen class MyApp { public static void main( String[] args ){ try { Schokolade ws = new Schokolade( "pink" ); ws.test(); } catch( IllegalSchokoColorException isce ) { System.err.println( "Falsche Schokoladen-Farbe" ); isce.printStackTrace(); } } } Mark Egloff 2006 53 Java Programmierung mit Exceptions Eigene Exception Klassen definieren z.B. Eigene Exception-Klasse werfen - Ausgabe Falsche Schokoladen-Farbe: IllegalSchokoColorException: Diese Schokoladen-Farbe gibt es nicht: pink at Schokolade.<init>(Schokolade.java:11) Mark Egloff 2006 54 Java Programmierung mit Exceptions Geschachtelte Exceptions > In Java lassen sich Exceptions ineinander verschachteln. Dies ist nützlich um z.B. Folgefehler zu kreieren > Ein Anwendungsfall wäre hierzu eine Transaktion. Ist ein Teil der Kette fehlerhaft, so ist der ganze Teil nicht ausführbar. > Eine geschachtelte Exception (engl. nested exception) speichert einen Verweis auf eine weitere Ausnahme. Wenn ein Exception-Objekt aufgebaut wird, lässt sich der Grund (engl. cause) als Argument im Konstruktor der Throwable-Klasse übergeben. Die Ausnahme-Basisklasse bietet dafür zwei Konstruktoren: > Throwable( Throwable cause ) > Throwable( String message, Throwable cause ) Mark Egloff 2006 55 Java Programmierung mit Exceptions Geschachtelte Exceptions z.B. Eine geschachtelte Exception erzeugen und behandeln public static void main( String[] args ){ try { throw new Exception( new Exception("inner")); } catch( Exception ex ) { Throwable cause ex.getCause(); cause.printStackTrace(); } } Bei generischen Fehlerbehandlungen muss deshalb speziell darauf geachtet werden, dass auch die „cause“ Exception ausgewertet wird Mark Egloff 2006 56 Java Programmierung mit Exceptions Tipps > Bestehender Programmfluss analysieren und verstehen, so dass Exceptions gezielt eingesetzt werden können > Nie eine Exception ignorieren und „catch“ Blöcke nie leer lassen! > Zuerst das das Exception-Objekt erzeugen und dann werfen. Danach Programm in sicheren Zustand bringen z.B. im „finally“ Block Ressourcen freigeben > Kein „return“ in einem „finally“ Block, da dies die Exception Behandlung unterbricht > Wenn möglich kein „return“ in einem „try“ Block, da dies oft Neulinge verwirrt > Den „finally“ Block verwenden um Ressourcen freizugeben Mark Egloff 2006 57 Java Programmierung mit Exceptions Tipps > Werfe keine Exceptions aus Konstruktoren. Innerhalb von Konstruktoren sollten keine kritischen Tasks erledigt werden. > Verwende kein Exceptionhandling für Programmfluss-Steuerungen > Wenn möglich „try/catch“ Blöcke ausserhalb von Schleifen verwenden > Weiterleitung von Exceptions beeinflussen die Methodendeklarationen und die Deklaration der „catch“ Blöcke. Nachträgliches ändern von Exceptionklassen kann daher eine Kettenreaktion auslösen. > Es sollte sehr sorgfältig zwischen „checked“ und „unchecked“ Exception ausgewählt werden. > Anstelle von vielen eigenen Exceptions eine Exceptionklasse mit Errorcode verwenden. Dies vereinfacht auch die Übersetzung der Fehlermeldungen im Falle von Mehrsprachigkeit Mark Egloff 2006 58 Java Programmierung mit Exceptions Zusammenfassung Exceptions Mark Egloff 2006 59