Wyjątki
Monika Wrzosek (IM UG) Programowanie obiektowe 180 / 207
Wyjątki
W Javie istnieje mechanizm tzw. wyjątków (ang. exception), który pozwala na przechwytywanie błędów pojawiających się w programie. Kompilacja
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t a b [ 1 0 ] = 1 0 0 ; }
}
spowoduje powstanie wyjątku związanego z przekroczeniem dopuszczalnego zakresu tablicy:
E x c e p t i o n i n t h r e a d " main "
j a v a . l a n g . A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n : 10 a t Main . main ( Main . j a v a : 4 )
Gdyby możliwości wyjątków kończyły się na wyświetlaniu informacji na ekranie i przerywaniu działania programu, ich przydatność byłaby mocno ograniczona.
Wygenerowany wyjątek można jednak przechwycić i wykonać własny kod obsługi błędu. Służy do tego blok instrukcji try...catch.
Schemat bloku try...catch try {
instrukcje mogące spowodować wyjątek }
catch (TypWyjątku identyfikatorWyjątku) { obsługa wyjątku
}
Na stronie https://docs.oracle.com/javase/8/docs/api/index.html w pakiecie java.lang. w Exception Summary zebrano różne rodzaje wyjątków, np:
ArithmeticException
ArrayIndexOutOfBoundsException ClassCastException
ClassNotFoundException IllegalAccessException
InstantiationException NegativeArraySizeException NoSuchFieldException NoSuchMethodException NullPointerException
Monika Wrzosek (IM UG) Programowanie obiektowe 182 / 207
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 1 0 0 ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n (" N i e p r a w i d ł owy i n d e k s t a b l i c y ! ") ; }
} }
Blok try...catch nie musi jednak obejmować tylko jednej instrukcji ani też tylko instrukcji mogących wygenerować wyjątek:
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { t r y {
i n t t a b [ ] = new i n t[ 1 0 ] ; t a b [ 1 0 ] = 5 ;
S y s t e m . o u t . p r i n t l n (" D z i e s i ą t y e l e m e n t t a b l i c y : " + t a b [ 1 0 ] ) ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n (" N i e p r a w i d ł owy i n d e k s t a b l i c y ! ") ; }
} }
Nie trzeba również obejmować blokiem try instrukcji bezpośrednio generujących wyjątek. Wyjątek wygenerowany przez obiekt klasy Y może być przechwytywany w klasie X, która korzysta z obiektów klasy Y.
p u b l i c c l a s s T a b l i c a {
p r i v a t e i n t[ ] t a b l i c a = new i n t[ 1 0 ] ; p u b l i c i n t p o b i e r z E l e m e n t (i n t i n d e k s ) {
r e t u r n t a b l i c a [ i n d e k s ] ; }
p u b l i c v o i d u s t a w E l e m e n t (i n t i n d e k s , i n t w a r t o s c ) { t a b l i c a [ i n d e k s ] = w a r t o s c ;
} }
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { T a b l i c a t a b l i c a = new T a b l i c a ( ) ;
t r y {
t a b l i c a . u s t a w E l e m e n t ( 5 , 1 0 ) ;
i n t l i c z b a = t a b l i c a . p o b i e r z E l e m e n t ( 1 0 ) ; S y s t e m . o u t . p r i n t l n ( l i c z b a ) ;
}
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n (" N i e p r a w i d ł owy i n d e k s t a b l i c y ! ") ; }
} }
Monika Wrzosek (IM UG) Programowanie obiektowe 184 / 207
p u b l i c c l a s s W y j a t k i { p u b l i c v o i d f ( ) {
t r y { g ( ) ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n (" Wyj ą t e k : metoda f ") ; }
}
p u b l i c v o i d g ( ) { t r y {
h ( ) ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n (" Wyj ą t e k : metoda g ") ; }
}
p u b l i c v o i d h ( ) { i n t[ ] t a b =new i n t[ 0 ] ; t r y {
t a b [ 0 ] = 1 ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n (" Wyj ą t e k : metoda h ") ; }
}
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { W y j a t k i e x =new W y j a t k i ( ) ;
t r y { e x . f ( ) ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n (" Wyj ą t e k : metoda main ") ; }
} }
Które bloki try zostaną wykonane? Zasada: zostanie wykonany blok znajdujący się
najbliżej instrukcji powodującej wystąpienie wyjątku. Zatem będzie to jedynie blok
obejmujący wywołanie instrukcji tab[0] = 1; w metodzie h.
Wyjątek jest obiektem
Schemat bloku try...catch try {
instrukcje mogące spowodować wyjątek }
catch (TypWyjątku identyfikatorWyjątku) { obsługa wyjątku
}
Wyjątek to obiekt powstający, kiedy w programie wystąpi sytuacja wyjątkowa.
Typ wyjątku to klasa opisująca ten obiekt.
Identyfikator wyjątku to zmienna obiektowa (referencyjna) wskazująca na obiekt wyjątku.
Monika Wrzosek (IM UG) Programowanie obiektowe 186 / 207
Wyjątek jest obiektem
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n (" N i e p r a w i d ł owy i n d e k s t a b l i c y ! ") ; S y s t e m . o u t . p r i n t l n (" Komunikat s y s t e m o w y : ") ;
S y s t e m . o u t . p r i n t l n ( e ) ; }
} }
N i e p r a w i d ł owy i n d e k s t a b l i c y ! Komunikat s y s t e m o w y :
j a v a . l a n g . A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n : 10
Hierarchia wyjątków
Każdy wyjątek jest obiektem pewnej klasy, które podlegają regułom dziedziczenia, np.
dla wyjątku ArrayIndexOutOfBoundsException:
Object -> Throwable -> Exception -> RuntimeException -> ArrayIndexOutOfBoundsException
Jeśli instrukcja może wygenerować wyjątek typu X, możemy przechwycić wyjątek ogólniejszy, czyli taki, którego typem będzie jedna z klas nadrzędnych do X.
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ; }
c a t c h(RuntimeException e ) {
S y s t e m . o u t . p r i n t l n (" N i e p r a w i d ł owy i n d e k s t a b l i c y ! ") ; S y s t e m . o u t . p r i n t l n (" Komunikat s y s t e m o w y : ") ;
S y s t e m . o u t . p r i n t l n ( e ) ; }
} }
Można również przechwycić wyjątek jeszcze bardziej ogólny:
c a t c h(Exception e )
Jeśli instrukcje, które są obejmowane blokiem try...catch, mogą spowodować wiele różnych wyjątków, zamiast stosować wiele oddzielnych instrukcji przechwytujących konkretne typy błędów, często lepiej jest użyć jednej przechwytującej wyjątek ogólniejszy.
Monika Wrzosek (IM UG) Programowanie obiektowe 188 / 207
Przechwytywanie wielu wyjątków
W jednym bloku try...catch można przechwytywać wiele wyjątków. Konstrukcja taka zawiera wtedy jeden blok try i wiele bloków catch.
Schemat bloku try...catch try {
instrukcje mogące spowodować wyjątek }
catch (KlasaWyjątku1 identyfikatorWyjątku1) { obsługa wyjątku
}
catch (KlasaWyjątku2 identyfikatorWyjątku2) { obsługa wyjątku
} . .
. catch (KlasaWyjątkuN identyfikatorWyjątkuN) { obsługa wyjątku
}
Po wygenerowaniu wyjątku następuje sprawdzenie, czy jest on klasy KlasaWyjątku1
(inaczej: czy jego typem jest KlasaWyjątku1). Jeśli tak - są wykonywane instrukcje
obsługi tego wyjątku i blok try...catch jest opuszczany. Jeżeli jednak wyjątek nie jest
klasy KlasaWyjątku1, następuje sprawdzenie, czy jest on klasy KlasaWyjątku2 itd.
Przechwytywanie wielu wyjątków
Kolejność przechwytywania wyjątków
nie ma znaczenia, o ile wszystkie wyjątki są na jednym poziomie hierarchii.
ma znaczenie, gdy przechwytuje się wyjątki z różnych poziomów:
najpierw muszą to być te bardziej szczegółowe (stojące niżej w hierarchii), potem bardziej ogólne (stojące wyżej w hierarchii).
Poniższy kod zakończy się błędem
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ; }
c a t c h( R u n t i m e E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ( e ) ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ( e ) ;
} } }
E x c e p t i o n i n t h r e a d " main "
j a v a . l a n g . E r r o r : U n r e s o l v e d c o m p i l a t i o n p r o b l e m :
U n r e a c h a b l e c a t c h b l o c k f o r A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n . I t i s a l r e a d y h a n d l e d by t h e c a t c h b l o c k f o r R u n t i m e E x c e p t i o n a t Main . main ( Main . j a v a : 1 0 )
Monika Wrzosek (IM UG) Programowanie obiektowe 190 / 207
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ; }
c a t c h( R u n t i m e E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ( e ) ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ( e ) ;
} }}
Wyjaśnienie: Błąd bardziej ogólny zawiera już w sobie błąd bardziej szczegółowy. Jeśli przechwyci się najpierw wyjątek RuntimeException, to tak jakby przechwycić już wyjątki wszystkich klas dziedziczących po RuntimeException. Poprawiony kod:
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ( e ) ;
}
c a t c h( R u n t i m e E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ( e ) ; }
}}
Przechwytywanie wielu wyjątków
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ;
i n t A [ ] = new i n t[ − 1 0 ] ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ("Z ł y i n d e k s ! ") ; }
c a t c h( E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("B ł ą d og ó l n y ") ; }
} }
Z ł y i n d e k s !
Pojawiło się zgłoszenie tylko pierwszego błędu.
Jeśli w bloku try któraś z instrukcji spowoduje wygenerowanie wyjątku, dalsze instrukcje z tego bloku nie zostaną wykonane (blok zostaje przerwany).
Monika Wrzosek (IM UG) Programowanie obiektowe 192 / 207
Przechwytywanie wielu wyjątków
Zmieńmy kolejność instrukcji w bloku try:
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
i n t A [ ] = new i n t[ − 1 0 ] ; t a b [ 1 0 ] = 5 ;
}
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ("Z ł y i n d e k s ! ") ; }
c a t c h( E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("B ł ą d og ó l n y ") ; }
} }
B ł ą d og ó l n y
Przechwytywanie wielu wyjątków
W Java 7 i nowszych dostępna jest możliwość przychwycenie kilku typów wyjątków w jednym bloku catch. Poszczególne typy należy oddzielić od siebie pionową kreską |. Wtedy niezależnie od tego, jaki wyjątek z wymienionych wystąpi, zostanie wykonany taki sam kod (zawarty w bloku catch).
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y {
t a b [ 1 0 ] = 5 ;
i n t A [ ] = new i n t[ − 1 0 ] ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n | N e g a t i v e A r r a y S i z e E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ("Z ł y i n d e k s l u b u j e m n y r o z m i a r t a b l i c y ") ;
}
c a t c h( E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("B ł ą d og ó l n y ") ; }
} }
Z ł y i n d e k s l u b u j e m n y r o z m i a r t a b l i c y
Monika Wrzosek (IM UG) Programowanie obiektowe 194 / 207
Zagnieżdżenie bloków try...catch
W jednym bloku przechwytującym wyjątek X może istnieć drugi blok, który będzie przechwytywał wyjątek Y.
Schemat zagnieżdżenia try {
instrukcje mogące spowodować wyjątek 1 try {
instrukcje mogące spowodować wyjątek 2 }
catch (TypWyjątku2 identyfikatorWyjątku2) { obsługa wyjątku 2
} }
catch (TypWyjątku1 identyfikatorWyjątku1) { obsługa wyjątku 1
}
Zagnieżdżenie bloków try...catch
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { i n t t a b [ ] = new i n t[ 1 0 ] ;
t r y { t r y {
t a b [ 1 0 ] = 5 ; }
c a t c h( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) { S y s t e m . o u t . p r i n t l n ("Z ł y i n d e k s ! ") ; }
i n t A [ ] = new i n t[ − 1 0 ] ; }
c a t c h( E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("B ł ą d og ó l n y ") ; }
} }
Z ł y i n d e k s ! B ł ą d og ó l n y
Monika Wrzosek (IM UG) Programowanie obiektowe 196 / 207
Zgłaszanie wyjątków
Wiemy już, że wyjątki można przechwytywać.
Wyjątki można również zgłaszać samemu, a także tworzyć nowe, nieistniejące wcześniej typy wyjątków.
Zgłoszenie/wyrzucenie wyjątku
Zgłoszenie/wyrzucenie wyjątku polega na:
- utworzeniu nowego obiektu klasy, która pośrednio lub bezpośrednio dziedziczy po klasie Throwable; w najogólniejszym przypadku będzie to klasa Exception - użyciu instrukcji throw
t h r o w new E x c e p t i o n ( ) ;
- Jeśli taki wyjątek zostanie obsłużony przez znajdującą się w danej metodzie instrukcję try...catch, nie trzeba robić nic więcej.
- Jeśli nie zostanie obsłużony (i nie jest wyjątkiem klasy RuntimeException lub pochodnej), w specyfikacji metody należy zaznaczyć, że może ona taki wyjątek zgłaszać - służy do tego instrukcja throws.
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) t h r o w s E x c e p t i o n { t h r o w new E x c e p t i o n ( ) ;
} }
Inaczej:
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) t h r o w s E x c e p t i o n { E x c e p t i o n e x = new E x c e p t i o n ( ) ;
t h r o w e x ; }
}
E x c e p t i o n i n t h r e a d " main " j a v a . l a n g . E x c e p t i o n a t Main . main ( Main . j a v a : 3 )
Monika Wrzosek (IM UG) Programowanie obiektowe 198 / 207
Można też zgłaszanemu wyjątkowi przypisać komunikat:
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) t h r o w s E x c e p t i o n { t h r o w new E x c e p t i o n (" Komunikat ") ;
} }
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) t h r o w s E x c e p t i o n { E x c e p t i o n e x = new E x c e p t i o n (" Komunikat ") ;
t h r o w e x ; }
}
E x c e p t i o n i n t h r e a d " main " j a v a . l a n g . E x c e p t i o n : Komunikat a t Main . main ( Main . j a v a : 3 )
Jeśli np. wykryjemy próbę dzielenia przez zero, możemy samodzielnie wygenerować wyjątek, nie czekając, aż zgłosi go maszyna wirtualna.
p u b l i c c l a s s D z i e l e n i e {
p u b l i c d o u b l e d z i e l (i n t a , i n t b ) { i f( b == 0 )
t h r o w new A r i t h m e t i c E x c e p t i o n (" D z i e l e n i e p r z e z z e r o : " + a + " / " + b ) ; r e t u r n a / b ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { D z i e l e n i e D = new D z i e l e n i e ( ) ;
d o u b l e w y n i k = D . d z i e l ( 2 0 , 1 0 ) ;
S y s t e m . o u t . p r i n t l n (" Wynik p i e r w s z e g o d z i e l e n i a : " + w y n i k ) ; w y n i k = D . d z i e l ( 2 0 , 0 ) ;
S y s t e m . o u t . p r i n t l n (" Wynik d r u g i e g o d z i e l e n i a : " + w y n i k ) ; }
}
E x c e p t i o n i n t h r e a d " main "
j a v a . l a n g . A r i t h m e t i c E x c e p t i o n : D z i e l e n i e p r z e z z e r o : 20/0 a t D z i e l e n i e . d z i e l ( D z i e l e n i e . j a v a : 4 )
a t D z i e l e n i e . main ( D z i e l e n i e . j a v a : 1 1 )
Monika Wrzosek (IM UG) Programowanie obiektowe 200 / 207
Ponowne zgłoszenie przechwyconego wyjątku
Do tej pory jeżeli przechwytywaliśmy wyjątek, jego obsługa ulegała zakończeniu.
Czasami istnieje jednak potrzeba, aby po wykonaniu bloku obsługi wyjątek nie był niszczony, ale przekazywany dalej.
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { t r y{
i n t l i c z b a = 1 0 / 0 ; }
c a t c h( A r i t h m e t i c E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("Tu w y j ą t e k z o s t a ł p r z e c h w y c o n y . ") ; t h r o w e ; // p o n o w n i e wyrzucamy w y j ą t e k
} } }
Ponieważ w programie nie ma innego bloku try...catch, który mógłby przechwycić ten wyjątek, zostanie on obsłużony przez maszynę wirtualną:
Tu w y j ą t e k z o s t a ł p r z e c h w y c o n y . E x c e p t i o n i n t h r e a d " main "
j a v a . l a n g . A r i t h m e t i c E x c e p t i o n : / by z e r o a t Main . main ( Main . j a v a : 4 )
Wyjątek przechwycony w bloku wewnętrznym i ponownie zgłoszony może być obsłużony w bloku zewnętrznym, w którym może być zgłoszony kolejny raz itd.
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { // t u d o w o l n e i n s t r u k c j e
t r y{
// t u d o w o l n e i n s t r u k c j e t r y{
i n t l i c z b a = 1 0 / 0 ; }
c a t c h( A r i t h m e t i c E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("Tu w y j ą t e k z o s t a ł p r z e c h w y c o n y p i e r w s z y r a z . ") ; t h r o w e ;
} }
c a t c h( A r i t h m e t i c E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n ("Tu w y j ą t e k z o s t a ł p r z e c h w y c o n y d r u g i r a z . ") ; t h r o w e ;
} } }
Tu w y j ą t e k z o s t a ł p r z e c h w y c o n y p i e r w s z y r a z . E x c e p t i o n i n t h r e a d " main "
Tu w y j ą t e k z o s t a ł p r z e c h w y c o n y d r u g i r a z . j a v a . l a n g . A r i t h m e t i c E x c e p t i o n : / by z e r o
a t Main . main ( Main . j a v a : 7 )
Monika Wrzosek (IM UG) Programowanie obiektowe 202 / 207
Tworzenie własnych wyjątków
Aby utworzyć własny wyjątek, należy napisać klasę pochodną pośrednio lub bezpośrednio z klasy Throwable.
W praktyce wyjątki zwykle są wyprowadzane z Exception i klas od niej pochodnych.
p u b l i c c l a s s Mo jWy ja tek e x t e n d s E x c e p t i o n { }
p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) t h r o w s Mo jWy ja tek { t h r o w new Mo jWy ja tek ( ) ;
} }
E x c e p t i o n i n t h r e a d " main " Mo jWy ja tek a t Main . main ( Main . j a v a : 5 )
p u b l i c c l a s s D i v i d e B y Z e r o E x c e p t i o n e x t e n d s A r i t h m e t i c E x c e p t i o n { }
p u b l i c c l a s s D z i e l e n i e {
p u b l i c d o u b l e d z i e l (i n t a , i n t b ) { i f( b == 0 )
t h r o w new D i v i d e B y Z e r o E x c e p t i o n ( ) ; r e t u r n a / b ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { D z i e l e n i e D = new D z i e l e n i e ( ) ;
d o u b l e w y n i k = D . d z i e l ( 2 0 , 1 0 ) ;
S y s t e m . o u t . p r i n t l n (" Wynik p i e r w s z e g o d z i e l e n i a : " + w y n i k ) ; w y n i k = D . d z i e l ( 2 0 , 0 ) ;
S y s t e m . o u t . p r i n t l n (" Wynik d r u g i e g o d z i e l e n i a : " + w y n i k ) ; }
}
Wynik p i e r w s z e g o d z i e l e n i a : 2 . 0
E x c e p t i o n i n t h r e a d " main " D i v i d e B y Z e r o E x c e p t i o n a t D z i e l e n i e . d z i e l ( D z i e l e n i e . j a v a : 6 )
a t D z i e l e n i e . main ( D z i e l e n i e . j a v a : 1 3 )
Pierwotnie przy zgłaszaniu wyjątku argumentem konstruktora był komunikat tekstowy.
Tutaj jest to niemożliwe, gdyż klasa DivideByZeroException nie ma konstruktora przyjmującego zmienną String, a jedynie bezargumentowy konstruktor domyślny.
Monika Wrzosek (IM UG) Programowanie obiektowe 204 / 207
p u b l i c c l a s s D i v i d e B y Z e r o E x c e p t i o n e x t e n d s A r i t h m e t i c E x c e p t i o n { p u b l i c D i v i d e B y Z e r o E x c e p t i o n ( S t r i n g s t r ) {
s u p e r( s t r ) ; }
}
p u b l i c c l a s s D z i e l e n i e {
p u b l i c d o u b l e d z i e l (i n t a , i n t b ) { i f( b == 0 )
t h r o w new D i v i d e B y Z e r o E x c e p t i o n (" D z i e l e n i e p r z e z z e r o : " + a + " / " + b ) ; r e t u r n a / b ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { D z i e l e n i e D = new D z i e l e n i e ( ) ;
d o u b l e w y n i k = D . d z i e l ( 2 0 , 1 0 ) ;
S y s t e m . o u t . p r i n t l n (" Wynik p i e r w s z e g o d z i e l e n i a : " + w y n i k ) ; w y n i k = D . d z i e l ( 2 0 , 0 ) ;
S y s t e m . o u t . p r i n t l n (" Wynik d r u g i e g o d z i e l e n i a : " + w y n i k ) ; }
}
Wynik p i e r w s z e g o d z i e l e n i a : 2 . 0 E x c e p t i o n i n t h r e a d " main "
D i v i d e B y Z e r o E x c e p t i o n : D z i e l e n i e p r z e z z e r o : 20/0 a t D z i e l e n i e . d z i e l ( D z i e l e n i e . j a v a : 9 )
a t D z i e l e n i e . main ( D z i e l e n i e . j a v a : 1 6 )
Sekcja finally
Do bloku try można dołączyć sekcję finally, która będzie wykonywana zawsze, niezależnie od tego, czy w bloku try wystąpi wyjątek, czy nie.
Schemat bloku try...catch...finally try {
instrukcje mogące spowodować wyjątek }
catch (TypWyjątku identyfikatorWyjątku) { obsługa wyjątku
} finally {
instrukcje }
Monika Wrzosek (IM UG) Programowanie obiektowe 206 / 207
p u b l i c c l a s s D z i e l e n i e {
p u b l i c d o u b l e d z i e l (i n t a , i n t b ) { i f( b == 0 )
t h r o w new D i v i d e B y Z e r o E x c e p t i o n (" D z i e l e n i e p r z e z z e r o ") ; r e t u r n a / b ;
}
p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { D z i e l e n i e D = new D z i e l e n i e ( ) ;
d o u b l e w y n i k ; t r y{
w y n i k = D . d z i e l ( 2 0 , 1 0 ) ; }
c a t c h( D i v i d e B y Z e r o E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n (" P r z e c h w y c e n i e w y j ą t k u 1 ") ; }
f i n a l l y{
S y s t e m . o u t . p r i n t l n (" S e k c j a f i n a l l y 1 ") ; }
t r y{
w y n i k = D . d z i e l ( 2 0 , 0 ) ; }
c a t c h( D i v i d e B y Z e r o E x c e p t i o n e ) {
S y s t e m . o u t . p r i n t l n (" P r z e c h w y c e n i e w y j ą t k u 2 ") ; }
f i n a l l y{
S y s t e m . o u t . p r i n t l n (" S e k c j a f i n a l l y 2 ") ; }
}}