catch

Werbung
Technische Universität Darmstadt
Telecooperation/RBG
Grundlagen der Informatik I
Thema 16: Ausnahmebehandlung
Dr. Guido Rößling
Copyrighted material; for TUD student use only
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Übersicht
• Fehler und deren Klassifizierung
• Fehlerbehandlung ohne eigenständige
Sprachmechanismen und deren Probleme
• Grundkonzepte der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Vorteile der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Zusammenfassung
Grundlagen der Informatik I: T16
2
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Klassifikation von Fehlern
• Lexikalische Fehler: Falsche oder unbekannte Worte
...
int[] result = neu int[5];
result.size();
// ...
//
• Syntaxfehler: Falsche Anordnung von Worten
//...
move();
public static void main(String[] args) {
// ...
}
//...
Lexikalische und syntaktische
Fehler werden vom Compiler
entdeckt und signalisiert
Grundlagen der Informatik I: T16
3
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Klassifikation von Fehlern
• Laufzeitfehler: ein Ereignis, das während des Ablaufs
eines Programms vorkommt und den normalen
Kontrollfluss der Anweisungen stört
à Fehlerterminierung
– Division durch 0
– Ein Grafikobjekt soll gezeichnet werden, existiert aber nicht
• Intentionsfehler: Programm läuft, aber mit
unerwünschtem Ergebnis
Grundlagen der Informatik I: T16
4
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung
• Umgang mit Fehlern ist ein wichtiger Teil der
Softwareentwicklung: Qualitätszusicherung!
• Die übliche Reaktion auf nicht abgefangene
Ausnahmesituationen: Programmabsturz!
– Das kann manchmal besser sein als fehlerhafte Ereignisse, die
für eine lange Zeit unentdeckt bleiben.
• Komplexe Programme/verteilte Anwendungen ohne jede
Reaktion auf Ausnahmen sind nicht akzeptabel.
• Telekommunikationssysteme
• Steuerungssysteme, z.B. Raketen, Kernkraftwerke, ...
• Programme, die tolerant (graceful) mit Fehlern umgehen,
werden robust genannt.
Grundlagen der Informatik I: T16
5
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung, Bug, Debugging
• Diese Vorlesung à Laufzeitfehler abfangen und beheben
– Schwerwiegende versus leichtgewichtige Fehler
• Foliensatz T19 à Intentionsfehler: Testen/verifizieren, dass die
Software das tut, was sie tun sollte
• Bug: Bezeichnung für alle Programmfehler
– Ursprung: Im einem Computer löste ein totes Insekt (engl. Bug) in
einem Relais einen Fehler aus
– Meist schwer zu finden, „100% Bug-free“ – unmöglich
• Debugging = Fehlersuche
• Beide Worte gehen auf Grace Murray Hopper (à T12.28) zurück
Grundlagen der Informatik I: T16
6
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Schwerwiegende Laufzeitfehler (Error)
• Zwei Sorten von schwerwiegenden Laufzeitfehlern
– Systemfehler: Fehler in der Java-VM,
Speichermangel, …
• Nicht „Schuld“ von Anwendungsprogrammierer
• Können prinzipiell nicht abgefangen werden und
führen direkt zum Programmabsturz
– Programmierfehler, nach denen eine
Programmfortsetzung nicht mehr möglich ist
• Eine benötigte Klasse ist nicht vorhanden
Grundlagen der Informatik I: T16
7
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Leichtgewichtige Fehler
• Ausnahmen (Exceptions) können innerhalb des Programms
abgefangen werden; Programmfortsetzung ist möglich.
Problem: Eingabe eines fehlerhaften Dateinamens
durch Benutzer
Behebung: Neueingabe verlangen
Problem: Fehlerhafte Daten in einer Datei, die ignoriert
werden können, z.B. nicht interpretierbare Bild- oder
Audiosignale
Behebung: Ignorieren
Problem: Zusammenbruch einer Netzverbindung
Behebung: Neuaufbau der Verbindung
Grundlagen der Informatik I: T16
8
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Einige typische Ausnahmen
public void printPerson() {
Person aPerson = null;
// ...
printName(aPerson);
// ...
}
public void printName(Person p) {
System.out.println(p.name);
}
• Problem: Sende eine Nachricht an "null"
• Ergebnis: NullPointerException
• Zugriff auf eine Methode oder Instanzvariable eines nichtexistierenden Objekts (null)
• Die Existenz eines Objekts sollte vor dem Zugriff geprüft werden!
Grundlagen der Informatik I: T16
9
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Einige typische Ausnahmen
int[] matrikelNummern = new int[27];
for (int i = 0; i <= 27; i++)
System.out.println(matrikelNummern[i]);
• Problem: illegaler Array-Zugriff mit i == 27
• Ergebnis: ArrayIndexOutOfBoundsException
• Gültig sind nur Positionen i mit 0 <= i < array.length
• Besonders trickreich bei Aufrufparametern
• Immer erst überprüfen, wie viele Argumente es gibt (args.length)
Grundlagen der Informatik I: T16
10
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Einige typische Ausnahmen
public static void main(String[] args) {
int count;
count = Integer.parseInt(args[1]);
// ...
}
Dieser Zugriff führt potentiell zu mehreren Fehlern!
Problem 1: illegaler Array-Zugriff, falls keine Parameter an
das Programm übergeben wurden. In diesem Fall hat args
keine Elemente – Zugriff auf args[1] schlägt fehl.
à
Ergebnis: ArrayIndexOutOfBoundsException
Problem 2: Versuch eine Nicht-Zahl zu parsen, falls args[1]
z.B. "Hello" ist. Text kann nicht in eine Zahl umgewandelt
werden.
à
Ergebnis: NumberFormatException
Grundlagen der Informatik I: T16
11
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung
• Zwei Arten von Fehlerbehandlung:
– Ohne eigenständige Sprachmechanismen
• In Sprachen wie C oder Pascal
– Mit eigenständigen Sprachmechanismen
• In Sprachen wie etwa Ada, Smalltalk, Java
• Im Folgenden werden wir
– Die Probleme der Sprachen ohne dedizierte
Fehlerbehandlungsmechanismen diskutieren
– Fehlerbehandlung mit dedizierten
Sprachmechanismen und deren Vorteile am
Beispiel von Java vorstellen
Grundlagen der Informatik I: T16
12
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Übersicht
• Fehler und deren Klassifizierung
• Fehlerbehandlung ohne eigenständige
Sprachmechanismen und deren Probleme
• Grundkonzepte der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Vorteile der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Zusammenfassung
Grundlagen der Informatik I: T16
13
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung ohne Sprachmechanismen
• Zwei Möglichkeiten von Fehlersignalisierung
– Programmabbruch (!) - Prozeduren/ Funktionen einer
Sprache, melden keine Fehler
• Zugriffsversuch auf eine nicht vorhandene Datei endete in
„alten“ Versionen von Pascal mit einem Programmabsturz.
– Fehler werden signalisiert
• Meist über unübliche Rückgabewerte von Methoden
• z.B. –1 statt positiver Zahl
• Abfangen und Behandlung von Fehlern
– Fehlerbehandlung wird (vom Programmierer) ignoriert
– Fehler werden behandelt, z.B. über Fallunterscheidungen
Grundlagen der Informatik I: T16
14
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung ohne Sprachmechanismen
• Wir betrachten den Fall:
– Unübliche Rückgabewerte zur Signalisierung
– Bedingungslogik zur Behandlung
• Problem: Keine Trennung der normalen Verarbeitung von der
Fehlerbehandlung
• Betrachten wir eine Methode (in Pseudocode), die eine ganze
Datei von der Festplatte in den Hauptspeicher liest.
readFile {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
}
Grundlagen der Informatik I: T16
15
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung ohne Sprachmechanismen
• Auf dem ersten Blick wirkt die Methode sehr simpel
• Aber sie ignoriert alle möglichen Fehler:
– Die Datei kann nicht geöffnet werden.
– Die Länge der Datei kann nicht festgestellt werden.
– Es ist nicht genug Platz im Hauptspeicher vorhanden.
– Lesen von der Datei schlägt fehl.
– Die Datei kann nicht geschlossen werden.
• Um diese Fälle zu behandeln, müssen wir eine Menge Code
hinzufügen, wie die folgende Implementierung zeigt.
Grundlagen der Informatik I: T16
16
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung ohne Sprachmechanismen
errorCodeType readFile {
initialize errorCode = 0;
open the file;
if (theFileIsOpen) {
determine its size;
if (gotTheFileLength) {
allocate that much memory;
if (gotEnoughMemory) {
read the file into memory;
if (readFailed) { errorCode = -1; }
} else { errorCode = -2; }
} else { errorCode = -3; }
close the file;
if (theFileDidntClose && errorCode == 0) {
errorCode = -4;
} else { errorCode = errorCode && -4; }
}
else { errorCode = -5; }
return errorCode;
}
Grundlagen der Informatik I: T16
17
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung ohne Sprachmechanismen
• Mit eingebauter Fehlerbehandlung bekommen wir 29 anstelle von 7
Zeilen Code - ein Faktor von fast 400%!
• Der Ursprungscode geht in dem Code für Entdeckung, Signalisierung
und Behandlung von Fehlern verloren.
• Der logische Fluss des Codes ist verloren gegangen, was die
Beurteilung, ob der Code das Richtige macht, sehr erschwert.
– Wird die Datei tatsächlich in dem Fall geschlossen, dass es nicht
genügend Speicherplatz gibt?
• Noch schwieriger wird es, wenn die Methode später modifiziert wird!
Grundlagen der Informatik I: T16
18
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Fehlerbehandlung ohne Sprachmechanismen
• Schlussfolgerung: Konflikt zwischen Zuverlässigkeit
und Übersichtlichkeit
– Werden Fehler behandelt, so entstehen
unübersichtliche Programmstrukturen (z.B. viele
Fallunterscheidungen)
– Werden Fehler ignoriert, so ist die Zuverlässigkeit
des Programms nicht sichergestellt
Eine Ausnahmebehandlung ohne eigenständige
Sprachkonstrukte hat sich nicht bewährt!
Grundlagen der Informatik I: T16
19
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Übersicht
• Fehler und deren Klassifizierung
• Fehlerbehandlung ohne eigenständige Sprachmechanismen
und deren Probleme
• Grundkonzepte der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Vorteile der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Zusammenfassung
Grundlagen der Informatik I: T16
20
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Ausnahmebehandlung in Java
• In Java werden Ausnahmen als Objekte dargestellt.
• Der Java-Compiler erzwingt die Behandlung von bestimmten Typen von
Fehlern.
• Wenn ein Fehler während der Ausführung einer Methode auftritt:
– Die Methode [oder das Laufzeitsystem] erzeugt und wirft ein AusnahmeObjekt, das Informationen über den Fehlertyp und Status des Programms,
als der Fehler passierte, usw. enthält
– Die Ausnahme wird ausgelöst: die Kontrolle und das erzeugte AusnahmeObjekt wird dem Laufzeitsystem übergeben.
– Das Laufzeitsystem sucht Code für die Behandlung der Ausnahme.
• Kandidaten dafür sind Methoden in der Aufrufkette der Methode, in der
der Fehler auftrat.
• Die Aufrufkette wird rückwärts durchsucht.
Grundlagen der Informatik I: T16
21
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Auslösen von Ausnahmen
public class Car {
public void start() {
// . . .
// battery might be empty
// driver might not be authorized
}
}
Die Batterien sind möglicherweise (fast) leer. Um einen
Programmabsturz zu vermeiden, soll eine Ausnahme ausgelöst
werden à BatteryLowException
Möglicherweise liegt keine Berechtigung vor, das Auto zu fahren
à Ausnahme: SecurityException
Grundlagen der Informatik I: T16
22
Auslösen von Ausnahmen
public class Car {
public void start() {
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Dieser Code wird vom
Übersetzer
so nicht akzeptiert!
if (batteryLevel <= 5)
throw new BatteryLowException(
"Battery is empty");
if (!driver.isAuthorized())
throw new SecurityException(
"No access rights");
// start the car
}
}
throw-Anweisung: throw Exception-Object.
Nebenbedingung: Exception-Object muss vom Typ
Exception abgeleitet sein (mehr gleich).
Fast immer direkt durch new erzeugt.
Grundlagen der Informatik I: T16
23
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Deklaration eventuell ausgelöster Ausnahmen
public class Car {
public void start()
throws BatteryLowException, SecurityException {
// . . .
// start car
}
}
Die Methode muss in der Signatur deklarieren, dass sie potentiell
Ausnahmen wirft! Potentiell ausgelöste Ausnahmen gehören zu der
Signatur einer Methode genau so wie der Rückgabetyp.
Syntax der Deklaration: throws <Exception-List>.
<Exception-List> = <Exception-Name>
{"," <Exception-List>}.
• Es können mehrere Ausnahmetypen deklariert werden
• Java Compiler überprüft, ob die Deklaration korrekt ist
– Können undeklarierte, unbehandelte Ausnahmen auftreten?
Grundlagen der Informatik I: T16
24
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Aufruf von Methoden, die Ausnahmen auslösen
public class Bar {
// ...
public void doSmthWithCar(Car car) {
// ...
car.start();
// ...
}
}
Dieser Code wird vom Übersetzer
nicht akzeptiert!
Grund: doSmthWithCar ruft eine Methode auf, welche
Ausnahmen auslösen könnte.
Diese werden aber ignoriert à Programmabsturz!
Grundlagen der Informatik I: T16
25
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Aufruf von Methoden, die Ausnahmen auslösen
public class Bar {
public void doSmthWithCar(Car car) {
// ...
try-Block signalisiert die Bereitschaft,
try {
auftretende Ausnahmen abzufangen
car.start();
und zu behandeln
}
catch (BatteryLowException ble) {
// Exception handling
Das Abfangen und die
}
Behandlung von
catch (SecurityException se) { Ausnahmen
erfolgt in
// Exception handling
catch-Blocks.
}
// ...
}
}
1. Möglichkeit:
Die aufrufende Methode behandelt die von
aufgerufenen Methoden erzeugten Ausnahmen
Grundlagen der Informatik I: T16
26
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Behandlung auftretender Ausnahmen
• Jeder catch-Block deklariert einen formalen Parameter
– Beispiel: catch(SecurityException se)
• Der Parametertyp legt den Ausnahmetyp fest, welchen der
catch-Block abfängt und behandelt
– Hier: SecurityException
• Der Parameter (hier: se) ist lokale Variable im catch-Block
– Erlaubt Verweise auf das zu behandelte Ausnahme-Objekt
– Erlaubt Zugriff auf Methoden oder Attribute der Ausnahme
• Ausnahmen sind im Prinzip ganz normale Java Objekte, definiert
in ganz normalen Java Klassen!
• Typische Methodenaufrufe:
– se.getMessage() – Zugriff auf Fehlermeldungstext
– se.printStackTrace() – Aufrufreihenfolge ausgeben
Grundlagen der Informatik I: T16
27
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Behandlung mehrerer Ausnahmen eines Blocks
Wie behandelt man mehrere mögliche Ausnahmen eines Befehls oder
Befehlsblocks?
• Es können mehrere catch-Blöcke zu einem try-Block angegeben
werden!
– Einzelne Befehle, die möglicherweise mehrere Ausnahmen
auslösen können, werden auch in einem try-Block
eingeschlossen.
• Es wird der erste passende catch-Block ausgeführt
– Vorsicht, wenn Ausnahmen in einer Vererbungsbeziehung stehen
(mehr gleich)!
Grundlagen der Informatik I: T16
28
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Weiterreichen auftretender Ausnahmen
public class Bar {
public void doSmthWithCar(Car car)
throws BatteryLowException, SecurityException {
// ...
car.start();
// ...
}
}
2. Möglichkeit:
Die aufrufende Methode reicht alle oder einige der
Ausnahmen entlang der Aufrufkette weiter.
Grundlagen der Informatik I: T16
29
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Weiterreichen auftretender Ausnahmen
public class Client {
public static void main(String[] args) {
// ...
Car car = ...; Bar o2 = new Bar();
o2.doSmthWithCar(car);
// ...
}
}
:Client
main
o2: Bar
:Car
o2.doSmthWithCar()
start()
Suche die erste Methode, die einen catch-Block für die ausgelöste
Ausnahme hat, und fahre mit dem Code im catch-Block fort.
Wird kein passender catch-Block gefunden, endet das Programm
mit einer Fehlermeldung.
Grundlagen der Informatik I: T16
30
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Sicherstellung der Ausführung von Aktionen
Wie kann sichergestellt werden, dass in jedem Fall bestimmte
Aktionen ausgeführt wurden?
• Problem: Bei Programmen mit Ausnahmebehandlung gibt es
mehrere Möglichkeiten, das Programm zu verlassen.
– Manchmal müssen bestimmte Aktionen garantiert werden,
egal, ob nun eine Ausnahme aufgetreten ist oder nicht.
• Beispiel: Schreiben in eine erfolgreich geöffnete Datei
– Die Datei sollte in jedem Fall geschlossen werden – egal, ob
Daten schreibbar waren oder nicht
Grundlagen der Informatik I: T16
31
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Der finally-Block
Code-Duplikation
public void test() {
Switch sw = new Switch();
try {
sw.on();
// code der evtl. Exceptions wirft
sw.off();
} catch (BatteryLowException e) {
sw.off();
// unnoetige Code-Duplikation
System.err.println("Caught BatteryLowException");
} catch (SecurityException e) {
sw.off();
// unnoetige Code-Duplikation
System.err.println("Caught SecurityException");
}
}
Grundlagen der Informatik I: T16
32
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Sicherstellung der Ausführung von Aktionen
• Dazu bietet Java den finally-Block
• Befehle des finally-Blocks werden immer ausgeführt:
– Nach Ende des try-Blocks, falls keine Ausnahme auftrat
– Nach Ende eines catch-Blocks, falls eine Ausnahme auftrat
public void test() {
Switch sw = new Switch();
try {
}
sw.on();
// code that may throw exceptions
} catch (BatteryLowException blExc) {
// ...
} catch (SecurityException secEx) {
// ...
}
finally {
sw wird auf jeden Fall
sw.off();
abgeschaltet, unabhängig vom
}
Kontrollfluss des Programms
Grundlagen der Informatik I: T16
33
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Vorteile des finally-Blocks
• Die Anweisungen des finally-Blocks werden
unabhängig vom Auftreten einer Ausnahme ausgeführt
– Keine Duplizierung von Code, der in jedem Fall – ob mit oder
ohne Exception – auszuführen ist
• Achtung:
– Befehle im finally-Block können wiederum
Ausnahmen auslösen!
• Schließen von Dateien oder
Netzwerkverbindungen, Null Pointer, ...
– Behandlung im finally-Block wie in jedem anderen
Block...
Grundlagen der Informatik I: T16
34
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Übersicht
• Fehler und deren Klassifizierung
• Fehlerbehandlung ohne eigenständige Sprachmechanismen
und deren Probleme
• Grundkonzepte der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Vorteile der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Zusammenfassung
Grundlagen der Informatik I: T16
35
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Vorteile der Fehlerbehandlung mit
eigenständigen Sprachmechanismen
1. Trennung der normalen Verarbeitung von der
Fehlerbehandlung
2. Weitergabe von Fehlern entlang der dynamischen
Aufrufkette
3. Unterscheidung und Gruppierung verschiedener
Fehlertypen
4. Kontrolle durch den Compiler, dass bestimmte
Fehlertypen auf jeden Fall behandelt werden
Grundlagen der Informatik I: T16
36
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
1. Trennung der Fehlerbehandlung
• Javas Konstrukte für
Ausnahmebehandlung
ermöglichen die Trennung
des normalen
Programmcodes von
Fehlerbehandlung
• Achtung! Ausnahmebehandlung erspart keine
Arbeit
– Der Vorteil liegt in der
Trennung.
void readFile() {
try {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
} catch (fileOpenFailed) {
doSomething;
} catch (sizeDeterminationFailed) {
doSomething;
} catch (memoryAllocationFailed) {
doSomething;
} catch (readFailed) {
doSomething;
} catch (fileCloseFailed) {
doSomething;
}
}
Grundlagen der Informatik I: T16
37
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
2. Fortpflanzung der Ausnahmen
• Angenommen, readFile ist die vierte Methode in einer Kette von
Methodenaufrufen: method1, method2, method3, readFile
– Dabei ist method1 die einzige Methode, die daran interessiert
ist, die Fehler von readFile zu behandeln.
• In traditionellen Sprachen müssen method2 und method3 die
Fehlerkodierungen weiterleiten, die von readFile zurückgegeben
werden, bis sie method1 erreichen.
method1 {
call method2;
}
method2 {
call method3;
}
method3 {
call readFile;
}
Grundlagen der Informatik I: T16
38
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
2. Fortpflanzung der Ausnahmen
method1 {
errorCodeType error;
error = call method2;
if (error)
doErrorProcessing;
else
proceed;
}
errorCodeType method3 {
errorCodeType error;
error = call readFile;
if (error)
return error;
else
proceed;
}
errorCodeType method2 {
errorCodeType error;
error = call method3;
if (error)
return error;
else
proceed;
}
Grundlagen der Informatik I: T16
39
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
2. Fortpflanzung der Ausnahmen
• Im Gegensatz dazu sucht das Laufzeitsystem von Java
rückwärts in der Aufrufkette nach Methoden, die an
der Behandlung der Fehler interessiert sind.
method1 {
try {
call method2;
} catch (exception) {
doErrorProcessing;
}
}
method2 throws exception {
call method3;
}
method3 throws exception {
call readFile;
}
Grundlagen der Informatik I: T16
40
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
3. Hierarchie der Java Ausnahmetypen
• Alle Ausnahmetypen in Java erben von der
vordefinierten Klasse java.lang.Throwable
“Schwerwiegende" VM Ausfälle sollen
und können nicht von einem Programm
abgefangen werden
können ignoriert
werden
können vom Programmierer
erweitert werden
Grundlagen der Informatik I: T16
41
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Die Klasse Throwable
Throwable
Erzeugt ein Throwable-Objekt
mit einer spezifischen
Fehlermeldung (error-message)
Throwable()
Throwable(String)
getMessage()
printStackTrace()
printStackTrace(PrintStream)
...
Gibt Fehlermeldung zurück
Gibt die Aufrufkette beim
Auslösen der Ausnahme aus
Grundlagen der Informatik I: T16
42
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Methoden der Klasse Exception
public class ExceptionMethods {
public static void main(String[] args) {
try {
throw new Exception("Hier kommt eine Exception");
} catch (Exception e) {
System.out.println("Exception gefangen");
System.out.println("e.getMessage(): "+e.getMessage());
System.out.println("e.toString(): "+e.toString());
System.out.println("e.printStackTrace():");
e.printStackTrace();
}
}
}
Grundlagen der Informatik I: T16
43
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Schwerwiegende Fehler: Error
• Programm kann nicht
• Es macht keinen Sinn,
fortgeführt werden, z.B. kein
solche Fehler abzufangen
Speicher mehr vorhanden
und zu behandeln: Der
Compiler erzwingt die
Behandlung von diesen
Fehlern nicht.
• Führen zum
Programmabsturz
Grundlagen der Informatik I: T16
44
Ungeprüfte Ausnahmetypen:
RuntimeException
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
• RuntimeExceptions sind Fehler, die überall im
Programm auftreten könnten, abhängig von
Laufzeitbedingungen:
– Aufrufen einer Methode auf einem null-Objekt, der Versuch
außerhalb der Grenzen eines Array zu lesen / schreiben, usw.
Diese Fehler können,
müssen aber nicht
abgefangen werden.
Grundlagen der Informatik I: T16
45
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Ungeprüfte Ausnahmetypen:
RuntimeException
• Das Erzwingen der Behandlung dieser Fehler würde das
Programm unnötig unübersichtlich machen
– Solche Fehler können potentiell überall auftreten …
• Ein catch-Block für NullPointerException wäre für jeden
Operationsaufruf notwendig
– Auch wenn der Programmierer sicher ist, dass eine Variable an
einer bestimmten Stelle des Programms ein gültiges Objekt enthält
– Der Compiler kann das statisch nicht testen
public static void main(String[] args) {
// evtl. ArrayIndexOutOfBoundsExc., NumberFormatException
Double doubleValue = Double.parseDouble(args[0]);
// evtl. ArrayIndexOutOfBoundsExc., NumberFormatException
Integer intValue = Integer.parseInt(args[1])
}
Grundlagen der Informatik I: T16
46
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Geprüfte Ausnahmetypen
• Geprüfte Ausnahmetypen sind alle Ausnahmetypen, die von
Exception aber nicht von RuntimeException erben
• Mehrere vordefinierte Ausnahmeklassen:
FileNotFoundException,IOException, etc.
Anwendungsspezifische Ausnahmen
können vom Programmierer als
direkte oder indirekte Erben von
Exception definiert werden.
Grundlagen der Informatik I: T16
47
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Geprüfte Ausnahmetypen
• Der Compiler erzwingt die Behandlung von geprüften
Ausnahmetypen
• Eine Methode muss für geprüfte Ausnahmen
– entweder eine Behandlung definieren (catch), oder
– alle Ausnahmen dieser Typen, die innerhalb des
Methodenbereiches vorkommen, weitergeben, indem sie in
einem throws-Ausdruck deklariert werden.
Der Bereich einer Methode M ist nicht nur der eigene Code, sondern auch
der Code von Methoden, die von M aufgerufen werden.
Diese Definition ist rekursiv.
Grundlagen der Informatik I: T16
48
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Gruppierung von Ausnahmetypen
• Exceptions sind normale Java-Objekte mit Vererbungshierarchie
• Daher kann man Spezialisierungen / Verallgemeinerungen
definieren zwischen den Exception-Typen
• Eine IndexOutOfBoundsException wird geworfen, wenn ein
Index außerhalb des gültigen Bereiches liegt
– ArrayIndexOutOfBoundsException ist eine Unterklasse
für Array-Zugriffe
– “Außerhalb des Bereichs”: Indexwert ist negativ oder größer
oder gleich der Array-Länge
• Der Programmierer einer Methode kann mehr oder weniger
spezifische Exceptions behandeln
Grundlagen der Informatik I: T16
49
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Gruppierung von Ausnahmetypen
Die Fassung von op1 behandelt
public void op1() {
verschiedene Exceptions
verschieden.
// ...
catch (ArrayIndexOutOfBoundsException invInd) {
// macht etwas mit invInd
}
catch (NullPointerException npe) {
// macht etwas mit npe
}
catch (NoSuchElementException eType) {
// macht etwas mit eType
}
}
public void op1() {
}
// ...
catch (RuntimeException e) {
// macht etwas mit e
}
Hier werden alle Exceptions
gleich behandelt.
Grundlagen der Informatik I: T16
50
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Gruppierung von Ausnahmetypen
public void op1() {
// ...
catch (RuntimeException e) {
// macht etwas mit e
}
}
Man könnte auch mit Fallunterscheidungen die
verschiedenen Subtypen von RuntimeException
unterscheiden. Die Fassung der vorherigen Folie ist:
• besser dokumentiert
• einfacher zu warten
public void op1() {
}
// ...
catch (Exception e) {
// macht etwas mit e
}
Man kann sogar alle
Exceptions gleich
behandeln.
NICHT EMPFOHLEN!
Grundlagen der Informatik I: T16
51
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Gruppierung von Ausnahmetypen
public void op1() {
// ...
catch (ArrayIndexOutOfBoundsException invInd) {
// macht etwas mit invInd
}
catch (RuntimeException e) {Laufzeitsystem wählt den ersten
// macht etwas mit e
catch-Block, der den Typ der
}
}
ausgelösten Ausnahme oder einen
Supertyp davon behandelt.
public void op1() {
// ...
catch (RuntimeException e) {
// macht etwas mit e
}
catch (ArrayIndexOutOfBoundsException invInd) {
// macht etwas mit invInd
}
}
Was passiert bei der Auslösung einer
ArrayIndexOutOfBoundsException?
Grundlagen der Informatik I: T16
52
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
„Vererbung“ von Ausnahmen
public
public
public
public
class
class
class
class
CarException extends Exception {}
NoGasoline extends CarException {}
NoSpecialGasoline extends NoGasoline {}
BadWeather extends Exception {}
public class Car {
public void start() throws NoGasoline { … }
public void stop() throws CarException { … }
}
public class SportsCar extends Car {
public void start() throws NoSpecialGasoline { … }
public void stop() throws BadWeather { … }
}
public static void main(String[] args) {
try {
new SportsCar().start();
} catch (NoSpecialGasoline e) { }
}
Dieser Code wird vom
Übersetzer
so nicht akzeptiert!
Grundlagen der Informatik I: T16
53
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
„Vererbung“ von Ausnahmen
• Gegeben sei eine Methode f, die Exceptions auslösen
kann und in einem Erben überschrieben wird.
• Regel 1: Der Erbe darf neben den im Vorfahr
deklarierten Exceptions auch konkretere Untertypen
davon werfen.
• Regel 2: Der Erbe darf keine zusätzlichen Exceptions
deklarieren, die nicht zu denen des Vorfahren passen.
– Es dürfen keine „neuen“ Exceptiontypen hinzugefügt werden.
– Konkretere Typen hingegen sind erlaubt (siehe Regel 1).
• Grund: Vererbungsregel 5 (à
Substituierbarkeit
T13.7) und
– Keine „Überraschung“ durch nicht erwartbare Exceptions bei
Verwendung der Basisklasse als statischen Typ!
Grundlagen der Informatik I: T16
54
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Konstruktoren und Ausnahmen
• Vor Aufruf des Konstruktors der Basisklasse darf nichts stehen,
nicht einmal ein try Block.
• Ausnahmen des Basisklassen-Konstruktors müssen im Konstruktor
der abgeleiteten Klasse wieder aufgelistet werden.
public class Car {
public Car() throws NoGasoline {}
}
public class SportsCar extends Car {
public SportsCar throws NoGasoline {
super(); //wirft vielleicht eine NoGasoline Ausnahme
//...
}
}
NoGasoline kann nicht mit
NoSpecialGasoline ersetzt werden
Grundlagen der Informatik I: T16
55
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Bedeutung von Namen
• Der Name einer Ausnahme ist typischerweise das
wichtigste.
• In der Regel wählt man lange, aussagekräftige Namen.
• Der Code der Ausnahmeklasse selbst ist meistens minimal.
• Nachdem man eine Ausnahme gefangen hat, benötigt man
sie in der Regel nicht mehr.
Grundlagen der Informatik I: T16
56
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Weiterleiten von Exceptions
catch (Exception e) {
System.out.println("An exception was thrown: "+e);
throw e;
// throw e.fillInStackTrace();
}
• So viel wie möglich direkt erledigen und dann eine
globalen Stelle den Rest erledigen lassen
• fillInStackTrace speichert im Throwable Objekt
Informationen über den aktuellen Zustand des AufrufStacks ab.
Grundlagen der Informatik I: T16
57
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Prüfen auf erwartete Ausnahmen in JUnit 4
• Erinnern Sie sich an den Taschenrechner mit JUnit in T12?
– Dort gab es eine Testmethode „divideByZero()“
– Diese wirft bei Aufruf eine ArithmeticException
• Wir wollen testen, ob diese erwartete Exception auftritt
– Wenn ja, ist das korrekt (erwartete Exception eingetreten)
– Wenn nein, ist das ein Fehler im Sinne des Testens
• Wie können wir die Exception über JUnit „abfangen“?
• Wir nutzen einen Parameter für die @Test-Annotation
– @Test(expected=ExceptionType.class)
• Im Beispiel also:
@Test(expected = ArithmeticException.class)
public void divideByZero() {
calculator.divide(0);
}
Grundlagen der Informatik I: T16
58
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Übersicht
• Fehler und deren Klassifizierung
• Fehlerbehandlung ohne eigenständige Sprachmechanismen
und deren Probleme
• Grundkonzepte der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Vorteile der Fehlerbehandlung mit eigenständigen
Sprachmechanismen am Beispiel von Java
• Zusammenfassung
Grundlagen der Informatik I: T16
59
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Zusammenfassung
•
•
Jedes Programm kann prinzipiell Fehler enthalten
Java unterstützt die Fehlerbehandlung
– Errors sind schwerwiegende Fehler à nicht behebbar
– Ausnahmen sind Fehler, die behoben werden können
•
Im wesentlichen drei Vorgehensweisen:
– Deklarieren und Weiterreichen der Ausnahme erfolgt durch
„throws“ und Ausnahmetyp im Methodenkopf
– Behandeln der Ausnahme(n) in try…catch der Methode
– Laufzeit-Ausnahmen können ignoriert, dürfen aber natürlich
auch behandelt werden!
Grundlagen der Informatik I: T16
60
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Zusammenfassung
• Die Exception-Behandlung erfolgt in try...catch
– Ausnahmen auslösende Befehle (meist Methodenaufrufe) stehen
in einem try-Block
– Mögliche Ausnahmen werden in catch-Blöcken behandelt
– Jeder catch-Block behandelt einen Ausnahmetyp
– Dazu wird ein Parameter vom Ausnahmetyp deklariert
• Die Suche nach dem „passenden“ catch erfolgt von oben
nach unten
– Der erste „passende“ catch-Block wird genutzt
– Bei der Anordnung ist die Vererbungshierarchie beachten!
• Befehle im finally-Block werden stets ausgeführt
– Egal, ob eine Ausnahme auftrat oder nicht
– Ideal, um „sauberzumachen“, etwa Dateien zu schließen
Grundlagen der Informatik I: T16
61
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Zusammenfassung: Kontrollfluss im Fehlerfall
Wie sieht der Kontrollfluss im Fehlerfall aus?
1. Erzeugung eines „passenden“ Ausnahme-Objekts
•
•
Das Ausnahme-Objekt beschreibt Problem und ggf. Ursache
• Aktuelle Klasse (Name!), evtl. Codezeile, Fehlerbeschreibung
(Text)
Die Anlegung des Ausnahme-Objekts kann erfolgen...
• „automatisch“ durch das Laufzeitsystem (z.B.
NullPointerException)
• durch Methodenaufrufe ausgelöst (z.B.
FileNotFoundException)
• durch den Programmierer mittels „throw new XXX()“
2. Die Laufzeitumgebung sucht nach passendem catch
•
•
•
Zunächst im aktuellen Block bis hin zur aktuellen Methode
Dann in der Methode, die diese Methode aufrief…
...und so weiter in der Aufrufkette, ggf. bis zum Start des Programms
Grundlagen der Informatik I: T16
62
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Ausnahme des Typs TE wird
in einem try-Block ausgelöst
Verlassen des try-Blocks
Durchsuchen der catch-Klauseln
catch-Klausel mit (Ober-)klasse
TE gefunden?
Ablauf:
Ausnahmebehandlung
nein
ja
Ausführung der Anweisungen
des ersten solchen catch-Blocks
Ausführung der Anweisungen
des (optionalen) finally-Blocks
Ausführung der Anweisungen
des (optionalen) finally-Blocks
catch-Block durchlaufen, ohne
neue Ausnahme auszulösen?
nein
ja
Fortsetzung hinter tryBlock
Grundlagen der Informatik I: T16
Weitergabe des neuen
Ausnahmeobjekts an den
umliegenden try-Blocks
63
Herunterladen