Tradycyjna obsługa błędów
PROSTY SCHEMAT OBSŁUGI WYJĄTKÓW W JAVIE
Wyjątek powstaje na skutek jakiegoś nieoczekiwanego błędu.
Wyjątek jest zgłaszany.
Wyjątek jest obsługiwany.
int a, b, c;
String s;
try {
// w bloku try ujmujemy instrukcje, które mogą spowodować wyjątek
a = b/c;
// jeżeli np. c = 0, zostanie zgłoszony wyjątek ArithmeticException
s = Integer.toString(a);
} catch(ArithmeticException ex) { // wyjątek jest obsługiwany
w bloku catch
s = "*" ;
}
Uwaga: w przypadku operacji na liczbach rzeczywistych przy dzieleniu przez 0 wyjątek nie zostanie zgłoszony, a wartość wyniku będzie POSITIVE_INFINITY (lub NEGATIVE_INFINITY), co po przeskztałceniu w String da napis "Infinity" ("-Infinity").
KLASY WYJĄTKÓW
Wyjątki są obiektami klas wyjątków.
(Żródło: Peter Haggar, Java Exception Handling, IBM 1999)
WYJĄTKI KONTROLOWANE I NIEKONTROLOWANE
Przykład:
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(args[0]);
out = new FileOutputStream(args[1]);
int c = 0;
while ((c = in.read()) != -1) out.write(c);
} catch(FileNotFoundException exc) {
System.out.println("Plik " + args[0] + " nie istnieje.");
System.exit(1);
} catch(IOException exc) {
System.out.println(exc.getMessage());
System.exit(1);
Gdybyśmy napisali metodę kopiującą strumienie:
public static void copyStream(InputStream in, OutputStream out)
throws IOException {
int c = 0;
while ((c = in.read()) != -1) out.write(c);
}
to obsługa wyjątku IOException, który może powstać przy read() musiałaby być prowadzona w miejscu wywołania metody:
try {
.....
copyStream(in, out);
} catch(IOException exc) { ... }
SEKWENCJA DZIAŁANIA
KLAUZULA FINALLY
Klauzula finally służy do wykonania kodu niezależnie od tego czy wystąpił wyjątek czy nie.
boolean metoda(...) {
try {
// instrukcje, które mogą spowodować
wyjątek
}
catch(Exception e) { return false; }
finally {
// uporządkowanie, np. zamknięcie
pliku
}
return true;
}
Jeśli powstał wyjątek - uruchamiana jest klauzula catch.
Mimo, iż zmienia ona sekwencję sterowania (zwraca false na znak, iż
nastąpiło niepowodzenie), sterowanie przekazywane jest do klauzuli finally.
I dopiero potem zwracany jest wynik - false.
Jeśli nie było wyjątku, po zakończeniu instrukcji w bloku try sterowanie
od razu wchodzi do klauzuli finally, a po jej zakończeniu zwracany jest
wynik true (wykonywana jest ostatnia instrukcja metody).
WŁASNE WYJĄTKI
Wyjątki są obiektami klas pochodnych od Throwable.
Żeby stworzyć własny wyjątek należy zdefiniować odpowiednią klasę.
Zgodnie z konwencją dziedziczymy podklasę Throwable - klasę Exception.
class NaszWyj extends Exception {
...
}
Zwykle w naszej klasie wystarczy umieścić dwa konstruktory: bezparametrowy oraz z jednym argumentem = komunikat o przyczynie powstania wyjątku.
Użycie wyjątku: