Info B VL 6: Exceptions

Transcription

Info B VL 6: Exceptions
Info B VL 6: Exceptions
Objektorientiere Programmierung in Java
2003
Ute Schmid (Vorlesung)
Elmar Ludwig (Übung)
FB Mathematik/Informatik, Universität Osnabrück
Info B VL 6: Exceptions – p.146
Fehler und Ausnahmen
Exception
Ereignis).
exceptional event (aussergewöhnliches
Ereignis, das während der Ausführung eines
Programms auftritt und den normalen Ablauf
unterbricht.
Java: “Fehlerereignisse” als Objekte (vom Typ
Exception) repräsentiert.
Exception und Error erweitern Throwable.
Error-Unterklassen betreffen schwerwiegende Fehler
(z.B. VirtualMachineError) und sollten nicht vom
Programmierer behandelt werden.
Exceptions sollten dagegen behandelt werden.
Exceptions treten typischerweise innerhalb von
Methoden auf.
Info B VL 6: Exceptions – p.147
Exception-Objekte
Wenn eine Exception auftritt (z. B.
FileNotFoundException wenn eine Datei, die
geöffnet werden soll, nicht gefunden wird), wird ein
Exception Objekt erzeugt und an das Laufzeitsystem
throwing an exception
gegeben.
Dieses Objekt enthält Information über die Art der
Exception und über den Zustand des Programms
(Aufrufstack) zum Zeitpunkt zu dem die Exception
auftrat.
Das Laufzeitsystem ist verantwortlich, Code zu finden,
der den Fehler behandelt. Die Behandlung kann in der
Methode, in der der Fehler aufgetreten ist, selbst oder
in einer der diese Methode aufrufenden Methoden
(Aufrufstack) erfolgen.
Info B VL 6: Exceptions – p.148
Exception-Handler
Beispiel:
h() -----------------> Exception tritt auf
g() (ruft h() auf)
f() (ruft g() auf)
Behandlung der Exception
Exception Handler (catch-Block): Für eine
aufgetretene Exception ist derjenige Handler
angemessen, der den entsprechenden Exception-Typ
(Klasse oder Oberklasse des geworfenen
Exceptionen-Objects) behandelt.
Wird eine aufgetretene Exception nicht behandelt,
terminiert das Laufzeitsystem und damit das
Programm.
Info B VL 6: Exceptions – p.149
Vorteile von Exceptions
Separierung von regulärem Code und
Fehlerbehandlung: Transparenz, Strukturiertheit
Propagierung von Fehlern möglich
Gruppierung von Fehler-Typen, Fehlerdifferenzierung
Info B VL 6: Exceptions – p.150
Beispiel
(in Pseudocode)
readFile {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
}
//
//
//
//
//
//
was ist, wenn
file nicht geoeffnet werden kann?
Laenge nicht bestimmt werden kann?
nicht genug Speicher belegt werden kann?
beim Lesen ein Fehler auftritt?
file nicht geschlossen werden kann?
Info B VL 6: Exceptions – p.151
Explizite Bedingungen
errorCodeType readFile {
initialize errorCode = 0;
open the file;
if (theFileIsOpen) {
determine the length of the file;
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 and -4; }
} else { errorCode = -5; }
return errorCode;
}
Info B VL 6: Exceptions – p.152
Trennung von Code und Fehlerbeh.
readFile {
{ // Block mit Anweisungen, wo Exc. auftreten koennten
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
} handle fileOpenFailed {
doSomething;
} handle sizeDeterminationFailed {
doSomething;
} handle memoryAllocationFailed {
doSomething;
} handle readFailed {
doSomething;
} handle fileCloseFailed {
doSomething;
}
}
Info B VL 6: Exceptions – p.153
Propagieren von Exceptions
(Beispiel in Pseudocode)
method1 {
call method2;
}
method2 {
call method3;
}
method3 {
call readFile;
}
Nur method1 sei an Fehlern, die in readFile() auftreten
können interessiert.
Info B VL 6: Exceptions – p.154
Propagierung “zu Fuss”
method1 {
errorCodeType error;
error = call method2;
if (error) doErrorProcessing;
else proceed;
}
errorCodeType method2 {
errorCodeType error;
error = call method3;
if (error) return error;
else proceed;
}
errorCodeType method3 {
errorCodeType error;
error = call readFile;
if (error) return error;
else proceed;
Info B VL 6: Exceptions – p.155
Propagierung mit ‘throws’
method1 {
try {
call method2;
} catch (exception) {
doErrorProcessing;
}
}
method2 throws exception {
call method3;
}
method3 throws exception {
call readFile;
}
Info B VL 6: Exceptions – p.156
Exception-Spezifikation
throws spezifiziert eine Exception:
Exception ‘Name’ kann in Methode ‘method’ auftreten
Spezifikation statt Behandlung: duck a thrown
exception
Behandlung mit catch
Laufzeitfehler müssen nicht spezifiziert/behandelt
werden
Alle anderen Exceptions dagegen schon! (checked
exceptions) Beispielcode: CloneCircle.java
javac CloneCircle.java
CloneCircle.java:89: unreported exception
java.lang.CloneNotSupportedException;
must be caught or declared to be thrown
return super.clone();
ˆ
Info B VL 6: Exceptions – p.157
‘RunTimeException’
o class java.lang.RuntimeException
+ class java.lang.ArithmeticException
+ class java.lang.ArrayStoreException
+ class java.lang.ClassCastException
+ class java.lang.IllegalArgumentException
class java.lang.IllegalThreadStateException
class java.lang.NumberFormatException
+ class java.lang.IllegalMonitorStateException
+ class java.lang.IllegalStateException
+ class java.lang.IndexOutOfBoundsException
class java.lang.ArrayIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
+ class java.lang.NegativeArraySizeException
+ class java.lang.NullPointerException
+ class java.lang.SecurityException
+ class java.lang.UnsupportedOperationException
Info B VL 6: Exceptions – p.158
Checked Exceptions
Beispiele: CloneNotSupportedException,
IOException und Unterklassen
werden von Methoden ausgelöst, RunTimeExceptions
vom Laufzeitsystem.
Es macht Sinn, dass verlangt wird, dass alle Fehler
ausser RunTimeExceptions vom Programmierer
behandelt werden.
Der Compiler/das Laufzeitsystem können nicht
hellsehen, auf welche Art eine Exception behandelt
werden soll.
Beispiel FileNotFoundException: Programm
beenden, andere Datei einlesen, File dieses Namens
erzeugen.
Info B VL 6: Exceptions – p.159
Gruppierung von Fehlertypen
Exception-Objekte sind – wie andere Java Objekte – in
einer Klassenhierarchie organisiert.
Alle Exceptions sind Instanzen von Throwable.
Ganze Gruppen von Exceptions können gemeinsam
behandelt werden, wenn eine entsprechende
Oberklasse verwendet wird.
Wenn mehrere catch-Blöcke den Typ der Exception
behandeln, so wird nur der erste (Reihenfolge im
Code) passende ausgeführt.
sequentielle Behandlung von der speziellsten zur
allgemeinsten
Achtung: Exception-Handler, die zu allgemein sind,
können Code wieder fehleranfällig machen! Es können
dadurch Exceptions gefangen werden, die nicht
vorhergesehen wurden und entsprechend nicht korrekt
Info B VL 6: Exceptions – p.160
behandelt werden.
Spezififkation mit ‘throws’
Beispielprogramm: ListOfNumbersDeclared.java
throws spezifiziert mögliche Fehler und verschiebt
deren Behandlung zu aufrufenden Methoden.
Dies macht Sinn, wenn es übergeordnete Strukturen
gibt, bei denen erst klar ist, welche Fehler wie
abgefangen werden sollen.
Es macht wenig Sinn, dass die main-Methode (letzte
Methode im Aufrufstack) Fehler spezifiziert und nicht
behandelt. Programmbenutzer wird dann mit den
java-Fehlermeldungen konfrontiert.
throws kann nur für Methoden (und Konstruktoren)
deklariert werden.
Info B VL 6: Exceptions – p.161
Vererbung und ‘throws’
Es ist nicht erlaubt, einer Methode beim Überschreiben
weitere throws-Klauseln hinzuzufügen!
Ansonsten wäre keine Zuweisungskompatibilität mehr
gegeben: In allen Methoden, die diese Methode
verwenden, müsste eine Spezifikation bzw.
Behandlung der neu hinzugekommenen Exceptions
erfolgen, was durch Casting zur Oberklasse
umgangen werden könnte.
Weglassen eines Teils oder einer kompletten
throws-Klausel ist erlaubt.
Info B VL 6: Exceptions – p.162
Exception Handling (1)
try -- catch -- finally
try-catch-finally ist eine Kontrollstruktur.
try-Block: wird verlassen, sobald eine Exception
auftritt
catch-Block: Fehlerbehandlung (es kann mehrere
catch-Blöcke geben)
finally-Block: sichert, dass bestimmte Dinge auf
jeden Fall ausgeführt werden (wenn vorher kein
System.exit() erfolgt), auch wenn etwas schief
geht. Beispiel: Schliessen einer Datei
Info B VL 6: Exceptions – p.163
Exception Handling (2)
try-finally: keine Fehlerbehandlung, sondern
Vermeidung von Redundanz im Code: Anweisungen in
finally werden auf jeden Fall ausgeführt (egal ob
der try-Block regulär oder wegen Exception
verlassen wird)
try-catch: Fehlerbehandlung
Exception-Objekte haben die Methode
getMessage(), die den Fehlertext der Exception
liefert.
Fehlermeldung in catch: mit
System.err.println()
sinnvoller als System.out.println():
Fehler-Strom soll auf Terminal, während der
Ausgabestrom z.B. in eine Datei gehen kann.
Info B VL 6: Exceptions – p.164
Beispiel
Beispielcode: ListOfNumbers.java
Drei Möglichkeiten des Programmablaufs:
new FileWriter() geht schief, IOException:
Entering try statement
Caught IOException: OutFile.txt
PrintWriter not open
ArrayIndexOutOfBoundsException:
Entering try statement
Caught ArrayIndexOutOfBoundsException: 10 >= 10
Closing PrintWriter
try-Block wird ohne Exception verlassen
Entering try statement
Closing PrintWriter
Info B VL 6: Exceptions – p.165
Definition und Auslösen von Excs.
Neue Exception-Klasse als Unterklasse von
Exception
throw new Exception() in Methode
Beispiel: IllegalRadiusException.java, CheckedCircle
Info B VL 6: Exceptions – p.166
Exkurs: UML
UML (“Unified Modeling Language”) ist eine auf
Diagrammen basierende Beschreibungssprache für
den objekt-orientierten Entwurf und die
objekt-ortientierte Analyse.
Standardisierte Notation zur Repräsentation von
Klassen und ihren Beziehungen
Standardisierung durch: Booch, Jacobson, Rumbaugh
(“Die drei Amigos”).
Meta-Modell legt fest, wie diese Sprache benutzt
werden soll.
Objekt-orientierter Entwurf meint die Konzeption von
Klassenstrukturen und Abhängigkeiten bei der
Systementwicklung.
Vorteile einer standardisierten Sprache:
CASE-Tools, Austausch von Entwürfen
Info B VL 6: Exceptions – p.167
Klassendiagramme
public abstract class Person {
protected String personName;
private int age;
public Person (String name) {
personName = name;
}
static public String makeJob () {return "hired";}
public int getAge () {return age;}
private void splitNames () {}
abstract String getJob ();
}
Info B VL 6: Exceptions – p.168
Beispiele
+Person
+getAge
getJob
+makeJob
−splitNames
Sichtbarkeits-Modifikatoren:
public, private,
protected
−age
#personName
Person
Kasten aus drei Teilen:
Klassen-Namen (fett),
Felder, Methoden
Kursiv: Abstrakte
Klassen/Methoden
Unterstrichen: Klassen-Methoden, Felder
Info B VL 6: Exceptions – p.169
Beispiele
Person
−age: Integer
#personName: String
Person
+Person(String)
+getAge(): Integer
getJob(): String
+makeJob(): String
−splitNames()
+getAge
getJob
+makeJob
−splitNames
Info B VL 6: Exceptions – p.170
Generalisierung
public class Employee extends Person {
public Employee (String name) {
super(name);
}
public String getJob() {
return "Research Staff";
}
}
Employee
+Employee
+getJob
Person
+getAge
getJob
+makeJob
−splitNames
Info B VL 6: Exceptions – p.171
Assoziationen
Allgemeine Beziehung zwischen Klassen (bzw.
Objekten):
Linie
Spezielle Assoziationen:
Generalisierung: ungefüllter Pfeil
Aggregation (Teil-Ganzes): ungefüllte Raute
Komposition (Teile können nicht ohne Ganzes
existieren): gefüllte Raute
Allgemein: Rolle, die einge Klasse bzgl. einer anderen
spielt
Rekursive Assoziation
Info B VL 6: Exceptions – p.172
Beispiel
public class Company {
Employee empt1;
Person per1;
public Company() {}
}
Person
Employee
public class Company1 {
Employee[] emp1;
public Company1() {}
}
0..1
per1
Company
0..1
emp1
Employee
*
emp1
Company1
Info B VL 6: Exceptions – p.173