wyklad 8 obsługa wątków


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 sieci
analiza finansowa wyklad Zdolnosc obslugi dlugu
wyklad teoria masowej obslugi
Wyklad 9 Jezyk SQL obsluga struktury?zy?nych indeksy widoki
GOI Wyklad 1 Zakres i uwarunkowania formalne, prawne i techniczne geodezyjnej obslugi inwestycji
10 Programowa obsługa sygnałów analogowych materiały wykładowe
Sieci komputerowe wyklady dr Furtak
Wykład 05 Opadanie i fluidyzacja
WYKŁAD 1 Wprowadzenie do biotechnologii farmaceutycznej
mo3 wykladyJJ
ZARZĄDZANIE WARTOŚCIĄ PRZEDSIĘBIORSTWA Z DNIA 26 MARZEC 2011 WYKŁAD NR 3
Wyklad 2 PNOP 08 9 zaoczne

więcej podobnych podstron