Vorlesung Informatik II Universität Augsburg Wintersemester 2011/2012 Prof. Dr. Bernhard Bauer Folien von: Prof. Dr. Robert Lorenz Lehrprofessur für Informatik 13. Java – Ausnahmebehandlung 1 Motivation In vielen Methoden können Fehler auftreten Division durch 0 Datei nicht gefunden Zugriff auf nicht vorhandene Elemente Setzen ungültiger Werte … 2 Motivation • Möglichkeiten der Behandlung solcher Fehler • Ignorieren: u.U. fatale Konsequenzen • Rückgabe eines besonderen Wertes: wird u.U. nicht geeignet • abgefangen • Ausgeben einer Fehlermeldung: unterbricht den Ablauf nicht • Sprung aus der fehlerhaften Methode: Ablaufstrukturen können • sehr kompliziert und unübersichtlich werden • Java: Exception-Klasse zur sauberen Behandlung von • Ausnahmen 3 Ausnahmebehandlung - Prinzipien Unterbrechung des Programmablaufs Ausnahmen müssen extra behandelt werden, sie können nicht ignoriert werden Trennung der Normalfälle von den Ausnahmefällen: Bessere Lesbarkeit der Programme Trennung von Entdecken und Behandeln der Ausnahme Ausnahme wird in einer Methode ausgelöst (thrown) Programmablauf verzweigt zu einer anderen Stelle An dieser Stelle findet Fehlerbehandlung statt (caught) Fortsetzung nach fehlerauslösendem Code (Rücksprung) 4 Ausnahmebehandlung - Prinzipien Unterscheidung verschiedener Ausnahmearten Zu jeder Ausnahmeart gibt es spezielle Anweisungen Java-Methoden lösen automatisch vordefinierte Ausnahmen aus Die Menge der möglichen Ausnahmen, auf die eine Methode reagieren kann, ist Bestandteil der Funktionalität dieser Methode (siehe API) Java-Programme können explizit Ausnahmen auslösen 5 Ausnahmebehandlung - Prinzipien Ausnahmen sind Java-Objekte Ein Ausnahme-Objekt kapselt Information über die Ausnahme für die Übergabe an die Fehlerbehandlung Es gibt viele vordefinierte Ausnahmen (API) Man kann eigene Ausnahmen-Objekte (Klassen) definieren 6 Ausnahmebehandlung - Prinzipien Vererbungshierarchie Ausnahmen (API) Throwable Error ... Exception RuntimeException ... ArithmeticException ... NullPointerException 7 Klasse Throwable Wurzelklasse für Ausnahmen…Einige Methoden Throwable() Konstruktor ohne Text-Fehlermeldung Throwable(String message) Konstruktor mit Text-Fehlermeldung String getMessage() Gibt Fehlermeldung zurück void printStackTrace() Ausgabe des Stacks der Methodenaufrufe bis zum Auftreten der Ausnahme auf System.err 8 Klasse Error Klasse für schwerwiegende Fehler, auf die normalerweise nur mit Programmabbruch reagiert werden kann. Beispiele IncompatibleClassChangeError NoSuchFieldError NoClassDefFoundError OutOfMemoryError ... 9 Klasse Exception Klasse für weniger schwerwiegende Fehler, nach deren geeigneter Behandlung das Programm fortgesetzt werden kann Eigene Ausnahmeklassen sind Unterklassen von Exception Beispiele IOException Oberklasse aller Ausnahmen durch I/O-Fehler EOFException Klasse für Fehler durch Lesen von Bytes „hinter“ dem Dateiende 10 Eigene Ausnahmeklassen Beispiele für Anwendung zur Verwaltung von Objekten: Kreieren eines bereits existierenden Objekts Eintragen von ungültigen Attributwerten Zugriff auf nicht vorhandene Objekte? (Bei Zugriff über Listen nicht möglich) Erfolglose Suche nach einem Objekt … 11 Eigene Ausnahmeklassen Beispiel: Ungültiger Attributwert import java.util.*; public class InvalidAttributeException extends Exception{ private String attribute; private Object object; public InvalidAttributeException(Object o, String a){ super("Ungültiger Attributwert"); attribute = a; object = o; } public String getAttribute(){return attribute;} public Object getObject(){return object;} } 12 Ausnahmen auslösen Bibliotheksoperationen und Konstruktoren lösen Ausnahmen aus Solche Operationen/Konstruktoren haben Prototyp der Form <Signatur> throws <Ausnahmenliste> Verlangt Ausnahmebehandlung durch den Aufrufer (sonst Compilerfehler) Beispiel Klasse Vector<T> public T elementAt(int i) throws ArrayIndexOutOfBoundsException Ausnahme bei Zugriff auf nicht besetzte Position 13 Ausnahmen auslösen Man kann Ausnahmen explizit auslösen durch Benutzung eines Konstruktors einer Ausnahmeklasse in der folgenden Form throw new <Exception>(<Parameterliste>); Beispiel Klasse Person: public void setVorname (String vorname) throws InvalidAttributeException{ if (checkName(vorname)==false){ throw new InvalidAttributeException(this,"Vorname"); } else{ this.vorname=vorname;} } 14 Ausnahmen abfangen Sequenzdiagramm: Auslösen einer Ausnahme mit throw und Ausnahmebehandlung durch Aufrufer <Aufrufer> <Klasse> try <Operation> throw new <Exception> e:<Exception> catch(e) <Ausnahmebehandlung> 15 Ausnahmen abfangen try...catch Programmstücke mit Operationen/Anweisungen, die Ausnahmen auslösen, werden in einen try{...}-Block eingeschlossen Fehlerbehandlungsroutinen finden in nachfolgenden (optionalen) catch(<Exception> e){…}-Blöcken statt In einem abschließenden (optionalen) finally{…}-Block spezifizierte Anweisungen werden immer ausgeführt 16 Ausnahmen abfangen try...catch Wird eine Ausnahme ausgelöst, so wird die Abarbeitung des tryBlocks abgebrochen und im ersten zum Ausnahmetyp passenden catch-Block fortgesetzt Nach Abarbeitung des catch-Blocks Fortsetzung nach den tryund catch-Blöcken 17 Ausnahmen abfangen • try...catch: mit mehreren verschiedenen möglichen • Ausnahmen • abfangen durch mehrere verschiedene catch-Blöcke • catch-Blöcke mit so speziellen Ausnahmetypen versehen wie möglich • catch-Blöcke zu spezielleren Ausnahmetypen kommen vor • catch-Blöcken zu allgemeineren Ausnahmetypen in der • Vererbungshierarchie • [denn spezielle Ausnahme-Objekte werden nach dem • Substitutionsprinzip auch für allgemeinere Typen eingesetzt!] 18 Ausnahmen abfangen try...catch: mit mehreren verschiedenen ausgelösten Ausnahmen Beispiel Datenhaltungsschicht: public Datei() { try{ Class.forName(driverClassName); con = DriverManager.getConnection (databaseUrl,user,password); } catch(ClassNotFoundException e){...} catch(SQLException e){...} } 19 Ausnahmen abfangen try...catch: finally-Block Für „Aufräumarbeiten“ da (z.B. Anweisungen rückgängig machen) Beispiel Datenhaltungsschicht: public void load(DatenContainer dataCon){ try{ Statement abfrage = con.createStatement(); String befehl = <Select-Ausdruck passend zu Klasse>; ResultSet ergebnis = abfrage.executeQuery(befehl); while (ergebnis.next()){ <Objekte erzeugen in Containern über dataCon> }} catch(SQLException e){...} finally{datacon.reset();} } 20 Ausnahmen abfangen • try...catch: Ort der Ausnahmebehandlung • Richtet sich nach dem Verantwortlichkeitsprinzip: • wer ist für die Funktionalität im Fehlerfall zuständig? • Welche anderen Anweisungen bilden eine Einheit mit • fehlerauslösenden Operationen? • • Öffnen eines Warndialogfensters aus Fachkonzeptklasse? Verhindern ungültige Werte Erzeugung eines Objekts? • Soweit wie nötig von Aufrufer zu Aufrufer weiterreichen • Individuelle Ausnahmebehandlung abhängig vom Aufrufer • möglich 21 Ausnahmen abfangen try...catch: Ort der Ausnahmebehandlung Voraussetzung für Weiterreichen der Ausnahmebehandlung: Auslösende Operation hat Prototyp der Form <Operationssignatur> throws <Exception> Zeigt dem Compiler an, dass der Aufrufer für die Ausnahmebehandlung sorgen muss Ist der Aufrufer eine Operation (außer main), so kann diese die Ausnahmebehandlung nach demselben Prinzip weiterreichen Ausnahmen vom Typ Error und RuntimeException müssen 22 nicht durch Prototypen bekannt gemacht werden Ausnahmen abfangen try...catch: Ort der Ausnahmebehandlung Beispiel Klasse PersonErfassenGUI: Weiterreichen von Fehlern in setVorname / setNachname an save private void save() { try { subject.setVorname(vorname.getText()); subject.setNachname(nachname.getText()); ... } catch(InvalidAttributeException e){ new InvalidAttributeDialog(this,e);} } 23 Ausnahmen abfangen try...catch: Ort der Ausnahmebehandlung Beispiel Klasse PersonErfassenGUI: Weiterreichen der Fehler von save an actionPerformed private void save() throws InvalidAttributeException{...} public void actionPerformed(ActionEvent e){... if (e.getActionCommand().equals("Speichern")){ try { ... save(); ... } catch(InvalidAttributeException exp){ new InvalidAttributeDialog(this,exp); }... } 24 Ausnahmen abfangen try...catch: Ort der Ausnahmebehandlung Diskussion des Beispiels: Ausnahmebehandlung in save verhindert nicht die Erzeugung eines Professoren-Objekts mit Eintragen in den Container: Objekt hat null-Werte (Ist das erwünscht?) Ausnahmebehandlung in actionPerformed erlaubt, bei ungültigen Werten das Eintragen des Objekts in den Container zu verhindern 25 Ausnahmen abfangen try...catch: Umfang des try-Blocks Nach der Fehlerbehandlung geht es nach den try- und catchBlöcken normal weiter im Code: Der try-Block sollte alle Anweisungen mit enthalten, die bei Auftreten eines Fehlers nicht mehr ausgeführt werden sollen 26 Ausnahmen abfangen try...catch: Umfang des try-Blocks Gegenbeispiel (Objekt trotz Fehler in Container eintragen) public void actionPerformed(ActionEvent e){ ... if (e.getActionCommand().equals("Speichern")){ subject = new Professor(); try { save();} catch(InvalidAttributeException exp){ new InvalidAttributeDialog(this,exp);} personen.addPerson(subject); dispose(); }... } 27 Arten der Fehlerbehandlung Modale Warndialoge Verhindern / Zurücksetzen von Datenänderungen "Anhalten" der Datenverarbeitung Programmabbruch 28