Zajęcia laboratoryjne nr 8 z programowania w języku Java - jedne zajęcia 1,5h. |
1. Wyjątki
Przez pojęcie wyjątków w językach obiektowych rozumiemy mechanizm kontroli przepływu
służący do obsługi zdarzeń wyjątkowych (w szczególności błędów). Wyjątek w języku
Java to obiekt, który opisuje pewną sytuację błędną lub nieprawidłową – wyjątkową.
Jest to obiekt odpowiedniego typu, tj. obiekt klasy Throwable
lub jej dowolnej
podklasy (np. Exception, Error itd.).
Ważną częścią każdej aplikacji jest sygnalizowanie oraz obsługa pojawiających się błędów. Wystąpienie błędu w aplikacji zaimplementowanej w języku Java sygnalizujemy poprzez rzucenie (wyrzucenie) wyjątku. Obsługa błędów to tzw. łapanie (przechwytywanie) wyjątków. |
Wyjątki dzielą się na dwa rodzaje:
-
kontrolowane - to takie które musimy deklarować i obsługiwać,
-
niekontrolowane - to takie które możemy obsługiwać, ale nie musimy.
Wyjątki niekontrolowane to instancje klas Error
i RuntimeException
oraz ich
dowolnych podklas. Wyjątki kontrolowane to instancje klas Throwable
i Exception
oraz ich podklas, z wyłączeniem podklas klas Error
i RuntimeException
. Wyjątki
mogą być rzucane (zgłaszane) przez Wirtualną Maszynę Javy (JVM) oraz przez
programistę. Najpopularniejszym wyjątkiem rzucanym przez JVM jest NullPointerException
.
Wyjątek ten rzucany jest przy próbie odwołania się do obiektu (np. próba uruchomienia metody)
z użyciem referencji, która ma wartość null
. NullPointerException
jest podklasą
klasy RuntimeException
tak więc jest wyjątkiem niekontrolowanym – nie musimy
go w żaden sposób deklarować czy obsługiwać.
2. Obsługa wyjątków
Wyjątki są wyrzucane i propagowane tak długo jak długo pozostają nie przechwycone
w kodzie programu. Wyjątki nie przechwycone propagują się aż do metody main(…)
i
jeśli także tam nie są przechwycone powodują przerwanie wykonania programu.
W celu przechwycenia i obsłużenia wyjątków w języku Java korzysta się z bloku try-catch-finally. |
Kod którego wyjątki chcemy przechwytywać umieszczamy w klauzuli try {…}
.
Wewnątrz klauzuli catch {…}
umieszczamy kod obsługi błędu - kod ten będzie
wykonany tylko i wyłącznie wówczas gdy kod programu wyrzuci wyjątek typu zgodnego
z typem określonym w deklaracji klauzuli catch. Kod umieszczony wewnątrz klauzuli
finally {…}
będzie wykonany zawsze, niezależnie od tego czy kod programu
wyrzucił wyjątek czy nie.
try {
//kod programu generujacy wyjatek
} catch (Exception e) {
//obsluga wyjatkow klasy Exception
} catch (Throwable t) {
//obsluga wyjatkow klasy Throwable
} finally {
//kod zawsze wykonywany
}
Gdy w wyniku wykonania instrukcji w bloku try powstanie wyjątek typu Exception
lub Throwable
to sterowanie zostanie przekazane do kodu umieszczonego w w/w klauzulach catch.
Klauzula finally jest opcjonalna, za to klauzul catch może być dowolnie wiele. |
class TestExceptions {
public static void main(String args[]) {
int d, a;
try {
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
} catch (ArithmeticException e) {
System.out.println("Division by zero.");
} finally {
System. out. println( "Finally") ;
}
System.out.println("Out of try/catch/finally - statement");
}
}
3. Generowanie (propagowanie) wyjątków
Wyjątki mogą być generowane jawnie w kodzie programu tj. przez programistę -
z użyciem słowa kluczowego throw
. Tak wygenerowany wyjątek może zostać obsłużony
bezpośrednio przez klauzulę catch
lub może zostać propagowany bezpośrednio
wyżej do metody wywołującej nasz kod (naszą metodę) w której został wyrzucony
wyjątek.
if (o == null)
throw new NullPointerException();
W istocie, instrukcja throw
jest niczym innym jak sposobem specyficznego
przekazywania sterowania do jakichś punktów programu (do miejsc obsługi wyjątku).
Należy jednak korzystać z niej wyłącznie w celu sygnalizowania błędów.
try {
...
} catch (Exception e) {
...
throw e; //ponowne wyrzucenie wyjątku
}
// propagowanie wyjątku którego obsługą zajmie się kod wywołujący metodę
void method() throws IOException {
}
class TestExceptions {
static void myMethod(int testnum) throws Exception {
System.out.println ("start - myMethod");
if (testnum == 12)
throw new Exception();
System.out.println("end - myMethod");
return;
}
public static void main(String args[]) {
int testnum = 12;
try {
System.out.println("try - first statement");
myMethod(testnum);
System.out.println("try - last statement");
}
catch ( Exception ex) {
System.out.println("An Exception");
}
finally {
System. out. println( "finally") ;
}
System.out.println("Out of try/catch/finally - statement");
}
}
4. Tworzenie własnych klas wyjątków
Oprócz wykorzystywania dostępnych klas wyjątków do generowania/obsługi sytuacji
wyjątkowych programista ma możliwość tworzenia własnych klas wyjątków. Żeby
stworzyć własny wyjątek należy zdefiniować odpowiednią klasę która dziedziczy
funkcjonalność z klasy Exception
.
class SuperWyjatek extends Exception { ... }
Zwykle w naszej klasie wystarczy umieścić dwa konstruktory: bezparametrowy oraz
z jednym argumentem typu String
(komunikat o przyczynie powstania wyjątku).
W konstruktorach tych należy wywołać konstruktor nadklasy (za pomocą odwołania
super(…)
, w drugim przypadku z argumentem String
).
class MyException extends Exception{
public MyException() {
System.out.println("Error");
}
}
class TestExceptions {
static void myMethod(int testnum) throws MyException {
System.out.println ("start - myMethod");
if (testnum == 12)
throw new MyException();
System.out.println("end - myMethod");
return;
}
public static void main(String args[]) {
int testnum = 12;
try {
System.out.println("try - first statement");
myMethod(testnum);
System.out.println("try - last statement");
}
catch ( MyException ex) {
System.out.println("An Exception");
}
finally {
System. out. println( "finally") ;
}
System.out.println("Out of try/catch/finally - statement");
}
}
5. Bibliografia
-
Bruce Eckels, "Thinking in Java. Edycja polska. Wydanie IV", wydawnictwo Helion.
-
Cay S. Horstmann, Gary Cornell, "Java. Podstawy. Wydanie IX", wydawnictwo Helion.
-
Cay S. Horstmann, Gary Cornell, "Java. Techniki zaawansowane. Wydanie IX", wydawnictwo Helion.
-
Krzysztof Barteczko, "Podstawy programowania w języku Java, PJWSTK", http://edu.pjwstk.edu.pl/wyklady/ppj/scb/
-
Konrad Kurczyna, "Laboratorium Java", Politechnika Świętokrzyska w Kielcach.
-
Mariusz Lipiński, "Nauka Javy", http://www.naukajavy.pl/