7. Java Fehler und Ausnahmen

Werbung
Fehler und Ausnahmen in Java
Fehler und Ausnahmen unterbrechen die
normale Programmausführung abrupt und
stellen eine nicht geplantes Ereignis dar.
7. Java Fehler und Ausnahmen
Ausnahmen sind böse, oder doch nicht?
Fehler, Systemausnahmen, Benutzerausnahmen, Behandeln von
Ausnahmen, Spezialfall Ressourcen
Java ermöglicht es, solche Ereignisse abzufangen und zu behandeln (als
Alternative zum Programmabsturz).
Nicht behandelte Fehler und Ausnahmen werden durch den Aufrufstapel
hochgereicht.
185
Fehler (Errors)
186
Ausnahmen (Exceptions)
Ausnahmen werden von der virtuellen Machine oder vom Programm
selbst ausgelösst und können meist behandelt werden um die
Normalsituation wiederherzustellen
Fehler treten in der virtuellen Machine
von Java auf und sind nicht reparierbar.
Beispiele
Beispiele
Kein Speicher mehr verfügbar
Zu hoher Aufrufstapel (→ Rekursion)
Dereferenzierung von null
Fehlende Programmbibliotheken
Division durch 0
Bug in der virtuellen Machine
Schreib/Lesefehler (Dateien)
Businesslogik Fehler
Computer-Hardwarefehler
Aufwischen und neu einschenken
Hier ist nichts mehr zu machen
187
188
Arten von Ausnahmen
Beispiel einer Systemausnahme
1
Systemausnahmen
(runtime exceptions)
2
Benutzerausnahmen
(checked exceptions)
3
4
5
Können überall auftreten
Müssen deklariert werden
Können behandelt werden
Müssen behandelt werden
Ursache: Bug im Programm
Ursache: Unwahrscheinliches, aber
prinzipiell mögliches Ereignis
6
7
8
9
10
11
import java. util .Scanner;
class ReadTest {
public static void main(String[] args){
int i = readInt("Zahl");
}
private static int readInt(String prompt){
System.out.print(prompt + ": ");
Scanner input = new Scanner(System.in);
return input.nextInt ();
}
}
Eingabe: Zahl: asdf
189
Nicht behandelte Fehler und Ausnahmen
190
Ausnahme propagiert durch Aufrufstapel
Das Programm stürzt ab und hinterlässt auf der Konsole eine
“Aufrufstapelzurückverfolgung” (ab jetzt: Stacktrace). Darin sehen
wir, wo genau das Programm abgebrochen wurde.
Java VM Runtime
Exception in thread "main" java. util .InputMismatchException
[...]
at java . util .Scanner.nextInt(Scanner.java:2076)
at ReadTest.readInt(ReadTest.java:9)
at ReadTest.main(ReadTest.java:4)
8
int i = readInt("Zahl");
ReadTest.readInt8
8
8
191
ReadTest.main();
ReadTest.main
8
⇒ Forensische Nachforschungen mit Hilfe dieser Information.
=
return input.nextInt();
Scanner.nextInt 8
192
Stacktraces verstehen
Ausgabe:
Stacktraces verstehen
Eine unpassende Eingabe ...
1
2
3
Exception in thread "main" java.util.InputMismatchException
at java . util .Scanner.throwFor(Scanner.java:864)
at java . util .Scanner.next(Scanner.java:1485)
at java . util .Scanner.nextInt(Scanner.java:2117)
at java . util .Scanner.nextInt(Scanner.java:2076)
at ReadTest.readInt(ReadTest.java:9)
at ReadTest.main(ReadTest.java:4)
4
5
6
7
8
9
10
11
... in Methode readInt auf Zeile 9 ...
... aufgerufen durch Methode main auf Zeile 4.
import java. util .Scanner;
class ReadTest {
public static void main(String[] args){
int i = readInt("Zahl");
}
private static int readInt(String prompt){
System.out.print(prompt + ": ");
Scanner input = new Scanner(System.in);
return input.nextInt ();
}
}
at ReadTest.readInt(ReadTest.java:9)
at ReadTest.main(ReadTest.java:4)
193
194
Systemausnahme: Bug im Programm?!
Intermezzo: Optionale Datentypen
Wo ist der Fehler?
Java bietet Klassen (Datentypen) an um optionale Werte explizit
darzustellen.
private static int readInt(String prompt){
System.out.print(prompt + ": ");
Scanner input = new Scanner(System.in);
return input.nextInt();
}
Beispiele:
Für int ⇒ OptionalInt
Für double ⇒ OptionalDouble
Für String ⇒ Optional<String> (generic, kommt später)
Nicht garantiert, dass als nächstes ein int anliegt.
Warum optionale Typen: Aufrufer/Benutzer kann selber entscheiden,
wann und wie mit abwesenden Werten umgegangen werden soll,
dies ohne Ausnahmen zu werfen.
⇒ Die Scanner Klasse bietet ein Test dafür an
⇒ Optionale Datentypen ermöglichen guten Stil
195
196
API von OptionalInt
API von OptionalInt
Benutzung von OptionalInt opt_i:
Erstellen eines optionalen ints:
Einen Standardwert wählen, falls leer:
Falls eine Zahl vorhanden ist:
int i = opt_i.orElse(−1);
i = 5;
OptionalInt opt_i = OptionalInt.of(i ); //Wert wird ’eingepackt’
Explizit prüfen ob eine Zahl vorhanden ist:
...
if (opt_i.isPresent ()){
int i = opt_i.getAsInt();
...
}
Falls keine Zahl vorhanden ist:
OptionalInt opt_i = OptionalInt.empty(); //Ein leerer Wert
197
Guter Code: Erst prüfen, optionales Resultat
198
Mögliche Behandlung von optionalen Datentypen
Entweder ein int oder leer
import java. util .OptionalInt;
private static OptionalInt readInt(String prompt){
System.out.print(prompt + ": ");
Scanner input = new Scanner(System.in);
Testet ob ein int
if (input.hasNextInt()){
return OptionalInt.of(input.nextInt()); am Input anliegt.
} else {
input.next(); // consume the wrong token Resultat in Opreturn OptionalInt.empty();
tionalInt ein}
packen
}
Standardwert benützen:
int x = readInt("x").orElse(0);
Nachfragen bis es stimmt:
OptionalInt opt_x;
while (!( opt_x = readInt("x")).isPresent()){
System.out.println("Please enter an integer " );
}
int x = opt_x.getAsInt();
Die aufrufende Methode kann entscheiden, was dann passiert
199
200
Erste Erkenntnis: Oft keine Ausnahmesituation
Zweite Erkenntnis: Ausnahmen verhindern
Oft sind die “Sonderfälle” gar kein besonderes Ereignis, sondern
absehbar. Hier sollten keine Ausnahmen verwendet werden!
Statt eine Systemausnahme abzuwarten aktiv verhindern, dass diese überhaupt auftreten kann.
Beispiele
Kinder kippen Becher um.
Man gewöhnt sich daran.
Beispiele
Falsche Credentials beim Einloggen
Usereingaben frühzeitig prüfen
Leere Pflichtfelder in Eingabemasken
Optionale Typen verwenden
Nicht verfügbare Internet-Ressourcen
Timeout Situationen voraussehen
Timeouts
Problem gelösst.
Plan B für nicht verfügbare Ressourcen
201
202
Arten von Ausnahmen
Beispiel einer Benutzerausnahme
Systemausnahmen
(runtime exceptions)
private static String[] readFile(String filename){
FileReader fr = new FileReader(filename);
BufferedReader bufr = new BufferedReader(fr);
...
line = bufr.readLine();
...
}
Benutzerausnahmen
(checked exceptions)
Können überall auftreten
Müssen deklariert werden
Können behandelt werden
Müssen behandelt werden
Compiler Fehler:
Ursache: Bug im Programm
Ursache: Unwahrscheinliches, aber
prinzipiell mögliches Ereignis
./Root/Main.java:9: error: unreported exception FileNotFoundException; must be caught or declared to be t
FileReader fr = new FileReader(filename);
^
./Root/Main.java:11: error: unreported exception IOException; must be caught or declared to be thrown
String line = bufr.readLine();
^
2 errors
203
204
Kurzer Blick in die Javadoc
Warum eine Benutzerausnahme?
Situation rechtfertigt die Benutzerausnahme:
Fehlerfall ist unwahrscheinlich aber prinzipiell möglich – und kann
durch geeignete Massnahmen zur Laufzeit behoben werden
können.
Der Aufrufer einer Methode mit einer deklarierten
Benutzerausnahme wird gezwungen, sich damit zu beschäftigen –
behandeln oder weiterreichen.
205
Behandeln von Ausnahmen
206
Behandlung von Ausnahmen: Propagieren stoppen!
private static String[] readFile(String filename){
try{
FileReader fr = new FileReader(filename);
BufferedReader bufr = new BufferedReader(fr);
Geschützter
...
Bereich
line = bufr.readLine();
...
} catch (IOException e){
Massnahmen zur Wiederher// do some recovery handling
stellung der Normalsituation
} finally {
// close resources
Wird in jedem Fall am
}
Schluss ausgeführt, immer!
}
ReadTest.main();
Java VM Runtime
ReadTest.main
lines = readFile("dataset.csv");
ReadTest.readFile 4
line = bufr.readLine();
Exception caught!
8
207
BufferedReader.readLine
8
208
Finally: Resourcen schliessen!
Try-with-resources Anweisung
Spezifische Syntax an, um Ressourcen automatisch zu schliessen:
In Java müssen Resourcen unbedingt geschlossen werden nach
Gebrauch. Ansonsten wird Speicher nicht freigegeben.
private static String[] readFile(String filename){
try ( FileReader fr = new FileReader(filename);
BufferedReader bufr = new BufferedReader(fr)) {
...
line = bufr.readLine();
...
Resourcen wer} catch (IOException e){
den hier geöffnet
// do some recovery handling
}
Resourcen werden hier automatisch geschlossen
}
Resourcen:
Dateien
Datenströme
GUI Elemente
...
209
210
Herunterladen