Wykład 8:
Obsługa Wyjątków
Wyjątki
Wyjątek to sytuacja nienormalna, która pojawia się w
trakcie wykonania programu.
W językach bez obsługi wyjątków, błędy są wykrywane i
obsługiwane ręcznie, zwykle przez kody błędów.
Java dostarcza specjalnych konstrukcji językowych do
sygnalizacji, wykrywania i obsługi błędów.
Wyjątki w Javie
Wyjątek to obiekt, który opisuje sytuację wyjątkową
(błędną) powstałą w kodzie programu:
Kiedy powstaje błąd, wyjątek opisujący go jest
"wyrzucany" w metodzie która ten błąd spowodowała.
Metoda może "wyłapać" i "obsłużyć" wyjątek
samodzielnie, lub przekazać go dalej.
Błąd jest na koniec wyłapany i obsługiwany.
Konstrukcje Obsługi Wyjątków
try otacza część programu, którą chcemy
monitorować na wypadek sygnalizacji błędów
catch w parze z try, wyłapuje określone wyjątki i
obsługuje je w pewien sposób
throw sygnalizuje powstanie określonego wyjątku
throws określenie jakie wyjątki może dana metoda
sygnalizować
finally kod, który musi być koniecznie wywołany
przed opuszczeniem danej metody
Blok Obsługi Wyjątków
Blok try/catch/finally do obsługi dwóch rodzajów
wyjątków (TypWyjatku1 i TypWyjatku2):
try {
//monitorowana część kodu
} catch(TypWyjatku1 e) {
//obsluga wyjatku dla typu 1
} catch(TypWyjatku2 e) {
//obsluga wyjatku dla typu 2
} finally {
//kod do wykonanie przed zakonczeniem
}
Hierarchia Wyjątków
Throwable obejmuje wszystkie wyjątki
Exception wyjątki do wyłapania przez
programy użytkowe
RuntimeException definiowane
automatycznie dla programów:
dzielenie przez zero
indeksowanie tablic
itp.
TypWyjatku wyjątki użytkownika
Error nie do wyłapania przez programy
użytkowe, błędy środowiska wykonawczego
Domyślna Obsługa Wyjątków
class Wyjatek0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
Gdy system wykrywa dzielenie przez zero, tworzy nowy
obiekt wyjątku, i wyrzuca go.
Z braku własnej procedury obsługi, wyjątek jest
przechwycony przez procedurę domyślną, która
wyświetla komunikat, stos wywołań i powoduje
zakończenie.
Domyślna Obsługa Wyjątków
Stos wywołań: ciąg wywołań metod które prowadziły do
wystąpienia błędu.
class Wyjatek1 {
static void metoda() {
int d = 0;
int a = 10 / d;
}
public static void main(String args[]) {
Wyjatek1.metoda();
}
}
Własna Obsługa Wyjątków
Korzyści własnej obsługi błędów: umożliwia poprawianie
błędów, zapobiega zakończeniu działania programu.
class Wyjatek2 {
public static void main(String args[]) {
int d, a;
Należy umieścić kod do monitorowania w bloku try:
try {
d = 0;
a = 42 / d;
System.out.println("Nieosiągalne");
}
Własna Obsługa Wyjątków
Należy określić które wyjątki chcemy wyłapać:
catch (ArithmeticException e) {
Oraz jak te wyjątki obsłużyć:
System.out.println("Dzielenie przez 0");
}
Kod po obsłudze wyjątku:
System.out.println("Po wyjatku");
}
}
Try i Catch
Bloki try i catch stanowią parę.
Gdy wyrzucany jest wyjątek w bloku try:
try {
d = 0;
a = 42 / d;
System.out.println("Nieosiągalne");
kontrola przechodzi natychmiast do bloku catch:
} catch (ArithmeticException e) { ... }
catch nie może wyłapać wyjątków z innych bloków try,
z wyłączeniem zagnieżdżonych bloków try.
Maskowanie Błędów
Wyjątek jest obsługiwany, potem program kontynuuje
tak jakby nic się nie wydarzyło.
Generowanie liczb losowych:
import java.util.Random;
class ObslugaBledow {
public static void main(String args[]) {
int a = 0, b = 0, c = 0;
Random r = new Random();
Maskowanie Błędów
Obsługa błędu gdy jedna z pary liczb jest zerem:
for (int i=0; i<32000; i++) {
try {
b = r.nextInt();
c = r.nextInt();
a = 12345 / (b / c);
} catch (ArithmeticException e) {
System.out.println("Dzielenie przez 0");
a = 0;
}
System.out.println("i: " + i + "a: " + a);
}
}
}
Wyświetlanie Opisu Wyjątku
Klasa Throwable przesłania metodę toString() tak
by wyświetlała opis wyjątku.
try { ... }
catch (ArithmeticException e) {
System.out.println("Wyjatek: " + e);
a = 0;
}
Obsługa Kilku Wyjątków Na Raz
Jeden blok try i kilka catch dla różnych wyjątków.
class WieleBledow {
public static void main(String args[]) {
try {
int a = args.length;
System.out.println("a= " + a);
Ryzyko dzielenia przez zero:
int b = 42 / a;
Indeks poza zakresem tablicy:
int c[] = { 1 }; c[42] = 99;
Obsługa Kilku Wyjątków Na Raz
Wyłapanie i obsługa błędu dzielenia przez zero:
} catch(ArithmeticException e) {
System.out.println("Dzielenie przez 0");
Wyłapanie i obsługa błędu indeksowania poza tablicą:
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Index poza tablica");
}
Kod po obsłudze błędów:
System.out.println("Po obsludze bledow");
}
}
Kolejność Obsługi Wyjątków
W sekwencji catch, wyjątki pod-klasy muszą wystąpić
przed wyjątkami nad-klasy. Pojawi się błąd kompilacji:
class WyjatekPodKlasa {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
} catch(Exception e) {
System.out.println("Wyjatek generyczny");
} catch(ArithmeticException e) {
System.out.println("Nieosiagalny");
}
}
}
Zagnieżdżony Blok try
Jeden blok try wewnątrz innego try.
class ZagniezdzonyTry {
public static void main(String args[]) {
Zewnętrzny blok try:
try {
int a = args.length;
Ryzyko dzielenia przez zero:
int b = 42 / a;
System.out.println("a= " + a);
Zagnieżdżony Blok try
Wewnętrzny blok try:
try {
Ryzyko dzielenia przez zero:
if (a == 1) a = a /(a-a);
Wykroczenie poza zakres tablicy:
if (a == 2) {
int c[] = {1};
c[42] = 99;
}
Zagnieżdżony Blok try
Obsługa wyjątku wykroczenia poza zakres tablicy
powstałego w bloku wewnętrznym try:
} catch(ArrayIndexOutOfBoundsException e){
System.out.println("Index za tablica");
}
Obsługa wyjątku błędu dzielenia przez zero powstałego
w bloku zewnętrznym try:
} catch (ArithmeticException e) {
System.out.println("Dzielenie przez 0);
}
}
}
Zagnieżdżony Blok try
wyjątek powstaje w bloku wewnętrznym try i jest
obsłużony przez catch w tym samym bloku
wyjątek powstaje w bloku wewnętrznym try i jest
obsłużony przez catch w bloku zewnętrznym
wyjątek powstaje w bloku zewnętrznym try i jest
obsłużony przez catch w bloku zewnętrznym
brakuje instrukcji catch w obu blokach - wyjątek
obsługiwany jest przez środowisko wykonawcze
Metody i Występowanie Bloków try
class MetodaZagniezdzonyTry {
Metoda z wewnętrznym blokiem try:
static void zagniezdzonyTry(int a) {
try {
if (a == 1) a = a /(a-a);
if (a == 2) {
int c[] = {1};
c[42] = 99;
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index poza tablica);
}
}
Metody i Występowanie Bloków try
Metoda z zewnętrznym blokiem try:
public static void main(String args[]) {
try {
int a = args.length;
int b = 42 / a;
System.out.println("a= " + a);
zagniezdzonyTry(a);
} catch (ArithmeticException e) {
System.out.println("Dzielenie przez 0);
}
}
}
Wyrzucanie Wyjątków
Program użytkownika może sam wyrzucać wyjątki:
throw object;
Obiekt musi być klasy Throwable, albo jej pod-klasy.
Uzyskanie obiektu klasy Throwable:
użycie operatora new
użycie parametru w instrukcji catch
Obsługa throw
Przerwanie wykonania na instrukcji throw:
czy najbliższy otaczający blok try posiada
instrukcję catch dla obsługi danego wyjątku?
w przeciwnym razie, czy kolejny otaczający blok try
posiada tą instrukcję?
w przeciwnym razie, wykonaj domyślną obsługę
wyjątku: przerwanie wykonania, drukowanie stosu
Demonstracja throw
class ThrowDemo {
static void metoda() {
try {
Tworzy nowy wyjątek i go wyrzuca:
throw new NullPointerException("demo");
Wyjątek jest wyłapany natychmiast:
} catch(NullPointerException e) {
System.out.println("Zlapany w metodzie");
Demonstracja throw
Obsługa polega na przesłaniu wyjątku dalej:
throw e;
}
}
Wyjątek jest złapany ponownie przez metodę main:
public static void main(String args[]) {
try {
metoda();
} catch(NullPointerException e) {
System.out.println("Zlapany ponownie");
}
}
}
Tworzenie Standardowych Wyjątków
Tworzenie obiektu standardowej klasy wyjątku:
throw new NullPointerException("demo");
Wszystkie standardowe wyjątki mają dwa konstruktory:
bezparametrowy
z parametrem String opisującym wyjątek; dostępny
przez getMessage() w Throwable
Deklaracja throws
Jeśli metoda może spowodować wyjątek którego sama
nie jest w stanie obsłużyć, to musi ten fakt opisać.
typ nazwa(parametry) throws wyjatki { ... }
Niezbędne jest wymienienie wszystkich wyjątków,
oprócz typów Error i RuntimeException.
Brak Deklaracji throws
Metoda wyrzuca wyjątek którego ani nie wyłapuje, ani
nie deklaruje. Ten program nie kompiluje się.
class ThrowsDemo1 {
static void metoda() {
System.out.println("Wewnatrz metody");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
metoda();
}
}
Dodana Deklaracja throws
Jedna metoda deklaruje, druga wyłapuje wyjątek:
class ThrowsDemo2 {
static void metoda()
throws IllegalAccessException {
System.out.println("Wewnatrz metody");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
metoda();
} catch (IllegalAccessException e) {
System.out.println("Zlapany " + e);
}
}
}
Deklaracja finally
Kod który będzie wykonany po bloku try/catch, bez
względu na powstanie wyjątków.
Użyteczny gdy należy zwolnić zasoby systemowe.
Każdy try musi posiadać co najmniej jedną instrukcję
catch lub finally.
Demonstracja finally
class FinallyDemo {
static void procA() {
try {
System.out.println("wewnatrz procA");
throw new RuntimeException("demo");
} finally {
System.out.println("procA: finally");
}
}
static void procB() {
try {
System.out.println("wewnatrz procB");
return;
} finally {
System.out.println("procB: finally");
}
}
Demonstracja finally
static void procC() {
try {
System.out.println("wewnatrz procC");
} finally {
System.out.println("procC: finally");
}
}
public static void main(String args[]) {
try {
procA();
} catch(Exception e) {
System.out.println("Wyjatek zlapany");
}
procB();
procC();
}
}
Standardowe Wyjątki Niesprawdzane
RuntimeException są dostępne automatycznie.
Nie muszą być deklarowane w sekcji throws.
Kompilator nie sprawdza czy metoda deklaruje czy
obsługuje te wyjątki.
Inaczej wyjątki niesprawdzane.
Standardowe Wyjątki Niesprawdzane
ArithmeticException błędy arytmetyczne, np.
dzielenie przez zero
ArrayIndexOutOfBoundsException indeks
tablicy poza zakresem
ArrayStoreException przypisanie tablicy
nieodpowiedniego typu elementu
ClassCastException niepoprawne rzutowanie
IllegalArgumentException niepoprawny
argument metody
IllegalMonitorStateException niepoprawna
operacja monitora
Standardowe Wyjątki Niesprawdzane
IllegalStateException środowisko lub aplikacja
jest w niepoprawnym stanie
IllegalThreadStateException wymagana
operacja niekompatybilna z bieżącym stanem wątka
IndexOutOfBoundException jakis rodzaj indeksu
jest poza zakresem
NegativeArraySizeException tablica tworzona z
ujemnym rozmiarem
NullPointerException niepoprawne użycie
wskaznika null
Standardowe Wyjątki Niesprawdzane
NumberFormatException niepoprawna konwersja
stringu na format liczbowy
SecurityException próba naruszenia
bezpieczeństwa
StringIndexOutOfBoundsException indeks poza
zakresem stringu
UnsupportedOperationException napotkano
niepoprawną operację
Standardowe Wyjątki Sprawdzane
Metody która mogą generować te wyjątki a nie potrafią
ich samodzielnie obsłużyć, muszą je deklarować:
ClassNotFoundException nie znaleziono klasy
CloneNotSupportedException próba klonowania
obiektu który nie implementuje interfejsu
Cloneable.
IllegalAccessException dostęp do klasy
zabroniony
InstantiationException próba tworzenia obiektu
klasy abstrakcyjnej lub interfejsu
Standardowe Wyjątki Sprawdzane
InterruptedException jeden wątek przerwany
przed drugi
NoSuchFieldException pole nie istnieje
NoSuchMethodException metoda nie istnieje
Tworzenie Własnych Klas Wyjątków
Utwórz pod-klasę Exception.
Pod-klasa nie musi nic deklarować, musi tylko istnieć.
Exception nie deklaruje własnych metod, ale
dziedziczy po Throwable.
Demonstracja Własnych Klas Wyjątków
Własna klasa wyjątków:
class MojWyjatek extends Exception {
private int szczegoly;
MojWyjatek(int a) {
szczegoly = a;
}
Przesłonięcie metody z klasy Throwable:
public String toString() {
return "MojWyjatek[" + szczegoly + "]";
}
}
Demonstracja Własnych Klas Wyjątków
class MojeWyjatki {
Metoda deklaruje wyjątek tej klasy:
static void oblicz(int a) throws MojWyjatek {
System.out.println("oblicz(" + a + ")");
Wyrzucenie wyjątku:
if (a > 10) throw new MojWyjatek(a);
System.out.println("Normalne wyjscie");
}
Demonstracja Własnych Klas Wyjątków
public static void main(String args[]) {
try {
oblicz(1);
oblicz(20);
Przechwycenie wyjątku:
} catch (MojWyjatek e) {
System.out.println("Zlapany " + e);
}
}
}
Wyszukiwarka
Podobne podstrony:
SO2 wyklad Obsługa siecianaliza finansowa wyklad Zdolnosc obslugi dluguwyklad teoria masowej obslugiWyklad 9 Jezyk SQL obsluga struktury?zy?nych indeksy widokiGOI Wyklad 1 Zakres i uwarunkowania formalne, prawne i techniczne geodezyjnej obslugi inwestycji10 Programowa obsługa sygnałów analogowych materiały wykładoweSieci komputerowe wyklady dr FurtakWykład 05 Opadanie i fluidyzacjaWYKŁAD 1 Wprowadzenie do biotechnologii farmaceutycznejmo3 wykladyJJZARZĄDZANIE WARTOŚCIĄ PRZEDSIĘBIORSTWA Z DNIA 26 MARZEC 2011 WYKŁAD NR 3Wyklad 2 PNOP 08 9 zaocznewięcej podobnych podstron