Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00148 009730 11027765 na godz. na dobę w sumie
Praktyczny kurs Java - książka
Praktyczny kurs Java - książka
Autor: Liczba stron: 384
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-395-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> java - programowanie
Porównaj ceny (książka, ebook, audiobook).

Poznaj tajniki najpopularniejszego języka programowania
w erze Internetu

Chyba wszyscy użytkownicy internetu spotkali się z Javą, często nawet o tym nie wiedząc. W ciągu ostatnich 10 lat zyskała ona ogromną popularność, szczególnie wśród programistów aplikacji sieciowych. Jednakże kojarzenie jej z językiem przeznaczonym wyłącznie do tworzenia takich programów jest dużym błędem. Java to w pełni funkcjonalny i doskonale dopracowany język programowania, nadający się do tworzenia różnych aplikacji, a nie tylko apletów działających na stronach internetowych.

W Javie pisane są gry sieciowe, systemy bankowości elektronicznej, pakiety wspomagające sprzedaż i obsługę klienta, a nawet aplikacje działające w telefonach komórkowych i komputerach przenośnych. Podstawową zaletą języka Java jest przenośność kodu -- raz napisany program można uruchomić na każdym urządzeniu, na którym zainstalowane jest odpowiednie środowisko uruchomieniowe, zwane JRE.

Książka 'Praktyczny kurs Java' przeznaczona jest dla osób rozpoczynających swoją przygodę z programowaniem w tym języku. Opisuje podstawy języka, zasady programowania obiektowego i tworzenia własnych apletów i aplikacji. Czytając kolejne rozdziały, dowiesz się:

Zapoznaj się z podstawami programowania w Javie i naucz się zasad programowania obiektowego, a także dowiedz się, czym są wyjątki w Javie i stwórz własne aplety i aplikacje.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI Praktyczny kurs Java KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Autor: Marcin Lis ISBN: 83-7361-395-1 Format: B5, stron: 384 Poznaj tajniki najpopularniejszego jêzyka programowania w erze Internetu Chyba wszyscy u¿ytkownicy internetu spotkali siê z Jav¹, czêsto nawet o tym nie wiedz¹c. W ci¹gu ostatnich 10 lat zyska³a ona ogromn¹ popularnoġæ, szczególnie wġród programistów aplikacji sieciowych. Jednak¿e kojarzenie jej z jêzykiem przeznaczonym wy³¹cznie do tworzenia takich programów jest du¿ym b³êdem. Java to w pe³ni funkcjonalny i doskonale dopracowany jêzyk programowania, nadaj¹cy siê do tworzenia ró¿nych aplikacji, a nie tylko apletów dzia³aj¹cych na stronach internetowych. W Javie pisane s¹ gry sieciowe, systemy bankowoġci elektronicznej, pakiety wspomagaj¹ce sprzeda¿ i obs³ugê klienta, a nawet aplikacje dzia³aj¹ce w telefonach komórkowych i komputerach przenoġnych. Podstawow¹ zalet¹ jêzyka Java jest przenoġnoġæ kodu -- raz napisany program mo¿na uruchomiæ na ka¿dym urz¹dzeniu, na którym zainstalowane jest odpowiednie ġrodowisko uruchomieniowe, zwane JRE. Ksi¹¿ka „Praktyczny kurs Java” przeznaczona jest dla osób rozpoczynaj¹cych swoj¹ przygodê z programowaniem w tym jêzyku. Opisuje podstawy jêzyka, zasady programowania obiektowego i tworzenia w³asnych apletów i aplikacji. Czytaj¹c kolejne rozdzia³y, dowiesz siê: • Jakie typy danych wykorzystywane s¹ w Javie • Jak deklarowaæ zmienne i wyprowadzaæ ich wartoġci na ekran • W jaki sposób sterowaæ przebiegiem wykonywania programu • Jakie zasady rz¹dz¹ programowaniem obiektowym • Czym s¹ klasy, obiekty, argumenty i metody • Co to s¹ wyj¹tki i jak je obs³ugiwaæ w programie • Jak wykorzystaæ zaawansowane techniki programowania obiektowego w swoich aplikacjach • W jaki sposób uzyskiwaæ dostêp do systemu plików z poziomu swojej aplikacji • Jak tworzyæ aplety i samodzielne aplikacje Zapoznaj siê z podstawami programowania w Javie i naucz siê zasad programowania obiektowego, a tak¿e dowiedz siê, czym s¹ wyj¹tki w Javie i stwórz w³asne aplety i aplikacje. Spis treści Wstęp ...................................................z............................................ 5 Rozdział 1. Podstawy ...................................................z....................................... 7 Lekcja 1. Struktura programu, kompilacja i wykonanie...............................................7 Lekcja 2. Podstawy obiektowości i typy danych ...................................................S.......9 Lekcja 3. Komentarze ...................................................S..............................................12 Rozdział 2. Instrukcje języka ...................................................z.......................... 17 .....17 Zmienne...................................................S...................................................S.................. Lekcja 4. Deklaracje i przypisania...................................................S...........................18 Lekcja 5. Wyprowadzanie danych na ekran ...................................................S............21 Lekcja 6. Operacje na zmiennych ...................................................S............................27 Instrukcje sterujące...................................................S...................................................S..... .39 Lekcja 7. Instrukcja warunkowa if...else ...................................................S.................39 Lekcja 8. Instrukcja switch i operator warunkowy ...................................................S..45 Lekcja 9. Pętle...................................................S...................................................S.......49 Lekcja 10. Instrukcje break i continue ...................................................S.....................56 Tablice...................................................S...................................................S.................. .......63 Lekcja 11. Podstawowe operacje na tablicach...................................................S.........64 Lekcja 12. Tablice wielowymiarowe ...................................................S.......................68 Rozdział 3. Programowanie obiektowe ...................................................z............ 79 ....79 Podstawy ...................................................S...................................................S................. Lekcja 13. Klasy, pola i metody ...................................................S..............................80 Lekcja 14. Argumenty i przeciążanie metod ...................................................S...........87 Lekcja 15. Konstruktory ...................................................S..........................................98 Dziedziczenie ...................................................S...................................................S............110 Lekcja 16. Klasy potomne ...................................................S.....................................110 Lekcja 17. Specyfikatory dostępu i pakiety ...................................................S...........118 Lekcja 18. Przesłanianie metod i składowe statyczne ..............................................132 Lekcja 19. Klasy i składowe i finalne ...................................................S....................145 Rozdział 4. Wyjątki ...................................................z...................................... 153 Lekcja 20. Blok try...catch ...................................................S.....................................153 Lekcja 21. Wyjątki to obiekty...................................................S................................162 Lekcja 22. Własne wyjątki...................................................S.....................................169 4 Praktyczny kurs Java Polimorfizm...................................................S...................................................S.............. Rozdział 5. Programowanie obiektowe II ...................................................z....... 181 .181 Lekcja 23. Konwersje typów i rzutowanie obiektów................................................181 Lekcja 24. Późne wiązanie i wywoływanie metod klas pochodnych .......................190 Lekcja 25. Konstruktory oraz klasy abstrakcyjne...................................................S..199 Interfejsy..........................................S...................................................S........................ .....209 Lekcja 26. Tworzenie interfejsów...................................................S..........................209 Lekcja 27. Wiele interfejsów ...................................................S.................................216 Klasy wewnętrzne ...................................................S...................................................S.....226 Lekcja 28. Klasa w klasie ...................................................S......................................226 Lekcja 29. Rodzaje klas wewnętrznych i dziedziczenie ...........................................235 Lekcja 30. Klasy anonimowe i zagnieżdżone...................................................S........244 Rozdział 6. System wejścia-wyjścia...................................................z............... 253 Lekcja 31. Standardowe wejście...................................................S............................253 Lekcja 32. Standardowe wejście i wyjście ...................................................S............263 Lekcja 33. System plików...................................................S......................................273 Lekcja 34. Operacje na plikach...................................................S..............................283 Rozdział 7. Aplikacje i aplety ...................................................z........................ 301 .....301 Aplety ...................................................S...................................................S................... Lekcja 35. Podstawy apletów ...................................................S................................301 Lekcja 36. Czcionki i kolory...................................................S..................................310 Lekcja 37. Grafika ...................................................S.................................................319 Lekcja 38. Dźwięki i obsługa myszy ...................................................S.....................330 Aplikacje ...................................................S...................................................S................ ...340 Lekcja 39. Tworzenie aplikacji...................................................S..............................340 Lekcja 40. Komponenty...................................................S.........................................359 Skorowidz...................................................z................................... 375 Rozdział 4. Wyjątki Praktycznie w każdym większym programie powstają jakieś błędy. Powodów jest bardzo wiele, może być to skutek niefrasobliwości programisty, założenia, że wpro- wadzone dane są zawsze poprawne, niedokładnej specyfikacji poszczególnych modu- łów aplikacji, użycia niesprawdzonych bibliotek czy nawet zwykłego zapomnienia o zainicjowaniu jednej tylko zmiennej. Na szczęście w Javie, tak jak i w większości współczesnych obiektowych języków programowania, istnieje mechanizm tzw. wyjąt- ków, który pozwala na przechwytywanie błędów. Ta właśnie tematyka zostanie przed- stawiona w kolejnych trzech lekcjach. Lekcja 20. Blok try...catch Lekcja 20. jest poświęcona wprowadzeniu w tematykę wyjątków. Zobaczymy, jakie są sposoby zapobiegania powstawaniu niektórych typów błędów w programach, dowiemy się, jak stosować przechwytujący błędy blok instrukcji VT[ECVEJ. Po- znamy bliżej wyjątek o nieco egzotycznej dla początkujących programistów nazwie #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQP, dzięki któremu będziemy mogli uniknąć błędów związanych z przekroczeniem dopuszczalnego zakresu inideksów tablic. Sprawdzanie poprawności danych Powróćmy na chwilę do rozdziału 2. i lekcji 11. Znajdował się tam przykład, w którym następowało odwołanie do nieistniejącego elementu tablicy (listing 2.38). Występowała tam sekwencja instrukcji: KPVVCD=?PGYKPV=? VCD=? Doświadczony programista od razu zauważy, że instrukcje te są błędne, jako że zade- klarowana została tablica dziesięcioelementowa, więc — ponieważ indeksowanie tablicy zaczyna się od zera — ostatni element tablicy ma indeks . Tak więc instrukcja VCD=? powoduje próbę odwołania się do nieistniejącego jedenastego elementu tablicy. Ten błąd jest jednak stosunkowo prosty do wychwycenia, nawet gdyby pomiędzy deklaracją tablicy a nieprawidłowym odwołaniem byłyi umieszczone inne instrukcje. 154 Praktyczny kurs Java Dużo więcej kłopotów mogłyby nam sprawić sytuacja, gdyby np. tablica była deklaro- wana w jednej klasie, a odwołanie do niej następowało w innej klasie. Taka przykładowa sytuacja została przedstawiona na listingu 4.1. Listing 4.1. RWDNKE ENCUU6CDNKEC ] RTKXCVGKPV=?VCDNKECPGYKPV=? RWDNKEKPVRQDKGT NGOGPV KPVKPFGMU ] TGVWTPVCDNKEC=KPFGMU? _ RWDNKEXQKFWUVCY NGOGPV KPVKPFGMUKPVYCTVQUE ] VCDNKEC=KPFGMU?YCTVQUE _ _ RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] 6CDNKECVCDNKECPGY6CDNKEC  VCDNKECWUVCY NGOGPV   KPVNKEDCVCDNKECRQDKGT NGOGPV   5[UVGOQWVRTKPVNP NKEDC  _ _ Powstały tu dwie klasy: 6CDNKEC oraz /CKP. W klasie 6CDNKEC zostało zadeklarowane prywatne pole typu tablicowego o nazwie VCDNKEC, któremu została przypisana dzie- sięcioelementowa tablica liczb całkowitych. Ponieważ pole to jest polem prywatnym (por. lekcja 17.), dostęp do niego mają jedynie inne składowe klasy 6CDNKEC. Dlatego też powstały dwie metody RQDKGT NGOGPV oraz WUVCY NGOGPV operujące na elemen- tach tablicy. Metoda RQDKGT NGOGPV zwraca wartość zapisaną w komórce o indeksie przekazanym jako argument, natomiast WUVCY NGOGPV zapisuje wartość drugiego argu- mentu w komórce o indeksie wskazywanym przez argumenit pierwszy. W klasie /CKP tworzymy obiekt klasy 6CDNKEC i wykorzystujemy metodę WUVCY NGOGPV do zapisania w piątej komórce wartości . W kolejnej linii popełniamy drobny błąd. W metodzie RQDKGT NGOGPV odwołujemy się do nieistniejącego elementu o indeksie . Musi to spowodować wystąpienie błędu w trakcie działania aplikacji (rysunek 4.1). Błąd tego typu bardzo łatwo popełnić, gdyż w klasie /CKP nie widzimy rozmiarów tablicy, nietrudno więc o pomyłkę. Rysunek 4.1. Odwołanie do nieistniejącego elementu w klasie Tablica Rozdział 4. ♦ Wyjątki 155 Jak poradzić sobie z takim problemem? Pierwszym nasuwającym się sposobem jest sprawdzanie w metodach RQDKGT NGOGPV i WUVCY NGOGPV, czy przekazane argumenty nie przekraczają dopuszczalnych wartości. Jeśli takie przekroczenie wartości nastąpi, należy wtedy zasygnalizować błąd. To jednak prowokuje pytanie: w jaki sposób ten błąd sygnalizować? Pomysłem znanym programistom C/C++ jest np. zwracanie przez funkcję (metodę) wartości Ō w przypadku błędu oraz wartości nieujemnej (najczę- ściej zero), jeśli błąd nie wystąpił1. Ta metoda będzie dobra w przypadku metody WUVCY NGOGPV, która wyglądałaby wtedy następująco: RWDNKEKPVWUVCY NGOGPV KPVKPFGMUKPVYCTVQUE ] KH KPFGMU VCDNKECNGPIVJ ] TGVWTPŌ _ GNUG] VCDNKEC=KPFGMU?YCTVQUE TGVWTP _ _ Wystarczyłoby teraz w klasie /CKP testować wartość zwróconą przez WUVCY NGOGPV, aby sprawdzić, czy nie przekroczyliśmy dopuszczalnego indeksu tablicy. Niestety, tej techniki nie można zastosować w przypadku metody RQDKGT NGOGPV, przecież zwraca ona wartość zapisaną w jednej z komórek tablicy. Czyli Ō i  użyte przed chwilą do zasygnalizowania, czy operacja zakończyła się błędem, mogą być wartościami odczyta- nymi z tablicy. Trzeba zatem wymyślić inny sposób. Może być to np. wykorzystanie dodatkowego pola sygnalizującego w klasie 6CDNKEC. Pole to byłoby typu DQQNGCP. Ustawione na VTWG oznaczałoby, że ostatnia operacja na klasie zakończyła się błędem, natomiast ustawione na HCNUG, że ostatnia operacja zakończyła się sukcesem. Klasa 6CDNKEC miałaby wtedy postać, jak na listingu 4.2. Listing 4.2. RWDNKE ENCUU6CDNKEC ] RTKXCVGKPV=?VCDNKECPGYKPV=? RWDNKEDQQNGCPY[UVCRKN$NCFHCNUG RWDNKEKPVRQDKGT NGOGPV KPVKPFGMU ] KH KPFGMU VCDNKECNGPIVJ ] Y[UVCRKN$NCFVTWG TGVWTP _ GNUG] Y[UVCRKN$NCFHCNUG TGVWTPVCDNKEC=KPFGMU? _ _ 1 To tylko przykład. Równie często stosuje się zwróczenie wartości zero jako oznaczenie prawidłowego wykonania funkcji. 156 Praktyczny kurs Java RWDNKEXQKFWUVCY NGOGPV KPVKPFGMUKPVYCTVQUE ] KH KPFGMU VCDNKECNGPIVJ ] Y[UVCRKN$NCFVTWG _ GNUG] VCDNKEC=KPFGMU?YCTVQUE Y[UVCRKN$NCFHCNUG _ _ _ Do klasy dodaliśmy pole typu DQQNGCP o nazwie Y[UVCRKN$NCF. Jego początkowa wartość to HCNUG. W metodzie RQDKGT NGOGPV sprawdzamy najpierw, czy przekazany indeks nie przekracza dopuszczalnej maksymalnej wartości. Jeśli tak, ustawiamy pole Y[UVCRKN$NCF na VTWG oraz zwracamy wartość zero. Oczywiście, w tym przypadku zwrócona wartość nie ma żadnego praktycznego znaczenia (przecież wystąpił błąd), niemniej coś musimy zwrócić. Użycie instrukcji TGVWTP i zwrócenie wartości typu KPV jest bowiem konieczne, inaczej kompilator zgłosi błąd. Jeśli jednak argument przeka- zany metodzie nie przekracza dopuszczalnego indeksu tablicy, pole Y[UVCRKN$NCF ustawiamy na HCNUG oraz zwracamy wartość znajdującą się pod tym indeksiem. W metodzie WUVCY NGOGPV postępujemy podobnie. Sprawdzamy, czy przekazany indeks nie przekracza dopuszczalnej wartości. Jeśli tak, pole Y[UVCRKN$NCF ustawiamy na VTWG, w przeciwnym przypadku dokonujemy przypisania wskazanej komórce tablicy i ustawiamy Y[UVCRKN$NCF na HCNUG. Po takiej modyfikacji obu metod w klasie /CKP możemy już bez problemów stwierdzić, czy operacje wykonywane na klasie 6CDNKEC zakończyły się sukcesem. Przykładowe wykorzystanie możliwości, jakie daje nowe pole, zostało przedstawione na listingu 4.3. Listing 4.3. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] 6CDNKECVCDNKECPGY6CDNKEC  VCDNKECWUVCY NGOGPV   KPVNKEDCVCDNKECRQDKGT NGOGPV   KH VCDNKECY[UVCRKN$NCF ] 5[UVGOQWVRTKPVNP 9[UVæRKđDđæF  _ GNUG] 5[UVGOQWVRTKPVNP NKEDC  _ _ _ Podstawowe wykonywane operacje są takie same, jak w przypadku klasy z listingu 4.1. Po pobraniu elementu sprawdzamy jednak, czy operacja ta zakończyła się sukcesem i wyświetlamy odpowiedni komunikat na ekranie. Identyczne sprawdzenie można Rozdział 4. ♦ Wyjątki 157 wykonać również po wywołaniu metody WUVCY NGOGPV. Wykonanie kodu z listingu 4.3 spowoduje rzecz jasna wyświetlenie napisu 9[UVæRKđDđæF (rysunek 4.2). Rysunek 4.2. Efekt wykonania programu z listingu 4.3 Sposobów poradzenia sobie z problemem przekroczenia indeksu tablicy można by zapewne wymyślić jeszcze kilka. Metody tego typu mają jednak poważną wadę: programiści mają tendencję do ich… niestosowania. Często możliwy błąd wydaje się zbyt banalny, aby się nim zajmować, czasami po prostu się zapomina się o sprawdza- niu pewnych warunków. Dodatkowo przedstawione wyżej sposoby, czyli zwracanie wartości sygnalizacyjnej czy dodatkowe zmienne, powodują niepotrzebne rozbudo- wywanie kodu aplikacji, co paradoksalnie może prowadzić do powstawania kolejnych błędów, czyli błędów powstałych przez napisanie kodu zajmującego się obsługą błę- dów… W Javie zastosowano więc mechanizm tak zwanych wyjątków, znany na pewno programistom C++ i Object Pascala2. Wyjątki w Javie Wyjątek (ang. exception) jest to byt programistyczny, który powstaje w sytuacji wy- stąpienia błędu. Z powstaniem wyjątku spotkaliśmy się już w rozdziale 2. w lekcji 11. Był to wyjątek spowodowany przekroczeniem dopuszczalnego zakresu tablicy. Po- każmy go raz jeszcze. Na listingu 4.4 została zaprezentowana odpowiednio spreparo- wana klasa /CKP. Listing 4.4. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] KPVVCD=?PGYKPV=? VCD=? _ _ Deklarujemy tablicę liczb typu KPV o nazwie VCD oraz próbujemy przypisać elementowi o indeksie  (czyli wykraczającym poza zakres tablicy) wartość . Jeśli skompilu- jemy i uruchomimy taki program, na ekranie zobaczymy obraz widoczny na rysunku 4.3. Został tu wygenerowany wyjątek o nazwie #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQP, czyli wyjątek oznaczający, że indeks tablicy znajduje sięi poza jej granicami. 2 Sama technika obsługi sytuacji wyjątkowych sięga jedznak lat sześćdziesiątych ubiegłego stulecia (czyli wieku XX). 158 Rysunek 4.3. Odwołanie do nieistniejącego elementu tablicy spowodowało wygenerowanie wyjątku Praktyczny kurs Java Oczywiście, gdyby możliwości wyjątków kończyłyby się na wyświetlaniu informacji na ekranie i przerywaniu działania programu, ich przydatność byłaby mocno ograni- czona. Na szczęście, wygenerowany wyjątek można przechwycić i wykonać własny kod obsługi błędu. Do takiego przechwycenia służy blok instrukcji VT[ECVEJ. W naj- prostszej postaci wygląda on następująco: VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM _ ECVEJ 6[R9[LæVMWKFGPV[HKMCVQT9[LæVMW ] QDUđWICY[LæVMW _ W nawiasach klamrowych występujących po słowie VT[ umieszczamy instrukcję, która może spowodować wystąpienie wyjątku. W bloku występującym po ECVEJ umieszczamy kod, który ma zostać wykonany, kiedy wyjątek wystąpi. W przypadku klasy /CKP z listingu 4.4 blok VT[ECVEJ należałoby zastosować sposób przedsta- wiony na listingu 4.5. Listing 4.5. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] KPVVCD=?PGYKPV=? VT[] VCD=? _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 0KGRTCYKFđQY[KPFGMUGVCDNKE[  _ _ _ Jak widać, wszystko odbywa się tu zgodnie z wcześniejszym ogólnym opisem. W bloku VT[ znalazła się instrukcja VCD=?, która — jak wiemy — spowoduje wygene- rowanie wyjątku. W nawiasach okrągłych występujących po instrukcji ECVEJ został wymieniony rodzaj wyjątku, który zostanie wygenerowany: #TTC[+PFGZ1WV1H$QWPFU å ZEGRVKQP, oraz jego identyfikator: G. Identyfikator to nazwa3, która pozwala na wykonywanie operacji związanych z wyjątkiem, czym jednak zajmiemy się w kolejnej Dokładniej jest to nazwa zmiennej obiektowej, wyjaśnzimy to bliżej w lekcji 21. 3 Rozdział 4. ♦ Wyjątki 159 lekcji. W bloku po ECVEJ znajduje się instrukcja 5[UVGOQWVRTKPVNP wyświetlająca odpowiedni komunikat na ekranie. Tym razem po uruchomieniu kodu zobaczmy widok zaprezentowany na rysunku 4.4. Rysunek 4.4. Wyjątek został przechwycony w bloku try…catch Blok VT[ECVEJ nie musi jednak obejmować tylko jednej instrukcji ani też tylko in- strukcji mogących wygenerować wyjątek. Przypomnijmy ponownie listing 2.38. Blok VT[ mógłby w tym wypadku objąć wszystkie trzy instrukcje, czyli klasa /CKP miałaby wtedy postać jak na listingu 4.6. Listing 4.6. ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] VT[] KPVVCD=?PGYKPV=? VCD=? 5[UVGOQWVRTKPVNP  KGUKæV[GNGOGPVVCDGNKE[OCYCTVQħè VCD=?  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 0KGRTCYKFđQY[KPFGMUGVCDNKE[  _ _ _ Nie istnieje również konieczność obejmowania blokiem VT[ instrukcji bezpośrednio generujących wyjątek, tak jak miało to miejsce w dotychczasowych przykładach. Wyjątek wygenerowany przez obiekt klasy ; może być bowiem przechwytywany w klasie :, która korzysta z obiektów klasy ;. Pokażemy to na przykładzie klas z listingu 4.1. Klasa 6CDNKEC pozostanie bez zmian, natomiast klasę /CKP zmodyfikujemy tak, aby miała wygląd zaprezentowany na listingu 4.7. Listing 4.7. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] 6CDNKECVCDNKECPGY6CDNKEC  VT[] VCDNKECWUVCY NGOGPV   KPVNKEDCVCDNKECRQDKGT NGOGPVG   5[UVGOQWVRTKPVNP NKEDC  _ 160 Praktyczny kurs Java ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 0KGRTCYKFđQY[KPFGMUGVCDNKE[  _ _ _ Spójrzmy, w bloku VT[ wykonujemy trzy instrukcje, z których jedna: KPV NKEDC  VCDNKECRQDKGT NGOGPV  jest odpowiedzialna za wygenerowanie wyjątku. Wyją- tek jest przecież jednak generowany w ciele metody RQDKGT NGOGPV klasy 6CDNKEC, a nie w klasie /CKP! Zostanie on jednak przekazany klasie /CKP, jako że wywołuje ona metodę klasy 6CDNKEC. Tym samym w klasie /CKP możemy zastosować blok VT[ECVEJ. Z identyczną sytuacją będziemy mieli do czynienia w przypadku hierarchicznego wywołania metod jednej klasy. Czyli w sytuacji, kiedy metoda H wywołuje metodę I, która wywołuje metodę J, która z kolei generuje wyjątek. W każdej z wymienionych metod można zastosować blok VT[ECVEJ do przechwycenia tego wyjątku. Dokładnie taki przykład jest widoczny na listingu 4.8. Listing 4.8. RWDNKE ENCUU ZCORNG ] RWDNKEXQKFH ] VT[] I  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCH  _ _ RWDNKEXQKFI ] VT[] J  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCI  _ _ RWDNKEXQKFJ ] KPV=?VCDPGYKPV=? VT[] VCD=? _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCJ  _ _ RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ]  ZCORNGGZPGY ZCORNG  Rozdział 4. ♦ Wyjątki 161 VT[] GZH  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCOCKP  _ _ _ Taką klasę skompilujemy bez żadnych problemów. Musimy jednak dobrze zdawać sobie sprawę, jak taki kod będzie wykonywany. Pytanie bowiem brzmi: które bloki VT[ zostaną wykonane? Zasada jest następująca: zostanie wykonany blok najbliższy instrukcji powodującej wyjątek. Czyli w przypadku przedstawionym na listingu 4.8 jedynie blok obejmujący wywołanie metody VCD=? w metodzie J. Jeśli jednak będziemy usuwać kolejne bloki VT[ najpierw z instrukcji J, następnie I, H i ostatecznie z OCKP, zobaczymy, że faktycznie wykonywany jest zawsze blok najbliższy miejsca wystąpienia błędu. Po usunięciu wszystkich instrukcji VT[ wyjątek nie zostanie obsłu- żony w naszej klasie i obsłuży go maszyna wirtualna Javy, co zaowocuje znanym nam już komunikatem na konsoli. Zwróćmy jednak uwagę, że w tym wypadku zostanie wy- świetlona cała hierarchia metod, w których był propagiowany wyjątek (rysunek 4.5). Rysunek 4.5. Przy hierarchicznym wywołaniu metod po wystąpieniu wyjątku otrzymamy ich nazwy Ćwiczenia do samodzielnego wykonania 20.1. Popraw kod klasy z listingu 4.2 tak, aby w metodach RQDKGT NGOGPV i WUVCY NGOGPV było również sprawdzane, czy przekazany indeks nie przekracza minimalnej dopusz- czalnej wartości. 20.2. Zmień kod klasy /CKP z listingu 4.3 w taki sposób, aby było również sprawdzane, czy wywołanie metody WUVCY NGOGPV zakończyło się sukcesem. 20.3. Popraw kod z listingu 4.2 tak, aby do wychwytywania błędów był wykorzysty- wany mechanizm wyjątków zamiast instrukcji warunkoweji KH. 20.4. Napisz klasę ZCORNG, w której będzie się znajdowała metoda o nazwie C, która z kolei będzie wywoływała metodę o nazwie D. W metodzie C wygeneruj wyjątek #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQP. Napisz następnie klasę /CKP zawierającą metodę OCKP, w której zostanie utworzony obiekt klasy ZCORNG i zostaną wywołane metody C oraz D tego obiektu. W metodzie OCKP zastosuj bloki VT[ECVEJ, przechwytujące powstały wyjątek. 162 Praktyczny kurs Java Lekcja 21. Wyjątki to obiekty W lekcji 20. poznaliśmy wyjątek sygnalizujący przekroczenie dopuszczalnego zakresu tablicy. To oczywiście nie jedyny dostępny wyjątek, czas poznać również inne ich typy. W lekcji 21. dowiemy się więc, że wyjątki są tak naprawdę obiektami, a także, że tworzą one hierarchiczną strukturę. Pokażemy, jak przechwytywać wiele wyjątków w jednym bloku VT[ oraz udowodnimy, że bloki VT[ECVEJ mogą być zagnieżdżane. Okaże się, że jeden wyjątek ogólny może obsłużyć wiele błędnycih sytuacji. Dzielenie przez zero Rodzajów wyjątków jest bardzo wiele. Wiemy już, jak reagować na przekroczenie zakresu tablicy. Poznajmy zatem inny typ wyjątku, powstający, kiedy zostanie podjęta próba wykonania nielegalnego dzielenia przez zero. W tym celu musimy spreparować odpowiedni fragment kodu. Wystarczy, że w metodzie OCKP umieścimy przykładową instrukcję: KPVNKEDC. Kompilacja takiego kodu przebiegnie bez problemu, jednak próba wykonania musi skończyć się komunikatem o błędzie, widocznym na rysunku 4.6. Widzimy wyraźnie, że tym razem został zgłoszony wyjątek #TKVJOGVKE ZEGRVKQP (wyjątek arytmetyczny). Rysunek 4.6. Próba wykonania dzielenia przez zero Wykorzystując wiedzę z lekcji 20., nie powinniśmy mieć żadnych problemów z napi- saniem kodu, który taki wyjątek przechwyci. Trzeba wykorzystać dobrze nam znaną instrukcję VT[ECVEJ w postaci: VT[] KPVNKEDC _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] KPUVTWMELGFQY[MQPCPKCMKGF[Y[UVæRKY[LæVGM _ Intuicja podpowiada nam już zapewne, że rodzajów wyjątków może być bardzo, bardzo dużo. I faktycznie tak jest, w klasach dostarczonych w JDK (w wersji SE) jest ich zdefiniowanych blisko 300. Aby sprawnie się nimi posługiwać, musimy dowiedzieć się, czym tak naprawdę są wyjątki. Wyjątek jest obiektem Wyjątek, który określaliśmy jako byt programistyczny, to nic innego jak obiekt, który powstaje, kiedy w programie wystąpi sytuacja wyjątkowa. Skoro wyjątek jest Rozdział 4. ♦ Wyjątki 163 obiektem, to wspominany wcześniej typ wyjątku (#TTC[+PFGZ1WV1H$QWPFU ZEGRVKQP, #TKVJOGVKE ZEGRVKQP) to nic innego jak klasa opisująca tenże obiekt. Jeśli teraz spoj- rzymy ponownie na ogólną postać instrukcji VT[ECVEJ: VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM _ ECVEJ 6[R9[LæVMWKFGPV[HKMCVQT9[LæVMW ] QDUđWICY[LæVMW _ jasnym stanie się, że w takim razie KFGPV[HKMCVQT9[LæVMW to zmienna obiektowa, wska- zująca na obiekt wyjątku. Na tym obiekcie możemy wykonywać operacje zdefiniowane w klasie wyjątku. Możemy np. uzyskać systemowy komunikat o błędzie. Wystarczy wywołać metodę IGV/GUUCIG . Zobaczmy to na przykładzie wyjątku generowanego podczas próby wykonania dzielenia przez zero. Jest on zaprezentowany na listingu 4.9. Listing 4.9. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] VT[] KPVNKEDC _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[UVCRKđY[LæVGMCT[VOGVG[EP[  5[UVGOQWVRTKPVNP -QOWPKMCVU[UVGOQY[ G 5[UVGOQWVRTKPVNP GIGV/GUUCIG  _ _ _ Wykonujemy tutaj próbę niedozwolonego dzielenia przez zero oraz przechwytujemy wyjątek klasy #TKVJOGVKE ZEGRVKQP. W bloku ECVEJ najpierw wyświetlamy nasze własne komunikaty o błędzie, a następnie komunikat systemowy. Po uruchomieniu kodu na ekranie zobaczymy widok zaprezentowany na riysunku 4.7. Rysunek 4.7. Wyświetlenie systemowego komunikatu obłędzie Istnieje jeszcze jedna możliwość uzyskania komunikatu o wyjątku, mianowicie umiesz- czenie w argumencie instrukcji 5[UVGOQWVRTKPVNP zmiennej wskazującej na obiekt wyjątku, czyli w przypadku listingu 4.9: 5[UVGOQWVRTKPVNP G  164 Praktyczny kurs Java W pierwszej chwili może się to wydawać nieco dziwne, bo niby skąd instrukcja 5[UVGOQWVRTKPVNP ma wiedzieć, co w takiej sytuacji wyświetlić? Zauważmiy jednak, że jest to sytuacja analogiczna, jak w przypadku typów prostych (por. lekcja 5.). Skoro udawało się automatycznie przekształcać np. zmienną typu KPV na ciąg znaków, uda się również przekształcić zmienną typu obiektowego. Bliżej tym problemem zajmiemy się w rozdziale piątym. Jeśli teraz z programie z listingu 4.9 zamienimy instriukcję: 5[UVGOQWVRTKPVNP GIGV/GUUCIG  na: 5[UVGOQWVRTKPVNP G  otrzymamy nieco dokładniejszy komunikat określający dodatkowo klasę wyjątku, tak jak jest to widoczne na rysunku 4.8. Rysunek 4.8. Pełniejszy komunikat o typie wyjątku Hierarchia wyjątków Każdy wyjątek jest obiektem pewnej klasy. Klasy podlegają z kolei regułom dziedzi- czenia, zgodnie z którymi powstaje hierarchia klas. Kiedy zatem pracujemy z wyjątkami, musimy tę kwestię wziąć pod uwagę. Wszystkie standardowe wyjątki, które możemy przechwytywać w naszych aplikacjach za pomocą bloku VT[ECVEJ, dziedziczą z klasy ZEGRVKQP, która z kolei dziedziczy z 6JTQYCDNG oraz 1DLGEV. Hierarchia klas dla wyjątku #TKVJOGVKE ZEGRVKQP, który wykorzystywaliśmy we wcześniejszych przykładach, jest zaprezentowana na rysunku 4.9. Rysunek 4.9. Hierarchia klas dla wyjątku ArithmeticException Wynika z tego kilka własności. Przede wszystkim, jeśli spodziewamy się, że dana instrukcja może wygenerować wyjątek typu :, możemy zawsze przechwycić wyjątek ogólniejszy, czyli wyjątek, którego typem będzie jedna z klas nadrzędnych do :. Jest to bardzo wygodna technika. Przykładowo z klasy 4WPVKOG ZEGRVKQP dziedziczy bar- dzo wiele klas wyjątków odpowiadających najróżniejszym błędom. Jedną z nich jest #TKVJOGVKE ZEGRVKQP. Jeśli instrukcje, które obejmujemy blokiem VT[ECVEJ, mogą Rozdział 4. ♦ Wyjątki 165 spowodować wiele różnych wyjątków, zamiast stosować wiele oddzielnych instrukcji przechwytujących konkretne typy błędów, często lepiej jest zastosować jedną prze- chwytującą wyjątek bardziej ogólny. Spójrzmy na listiing 4.10. Listing 4.10. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] VT[] KPVNKEDC _ ECVEJ 4WPVKOG ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[UVCRKđY[LæVGMECUWGY[MQPCPKC  5[UVGOQWVRTKPVNP -QOWPKMCVU[UVGOQY[ G 5[UVGOQWVRTKPVNP G  _ _ _ Jest to znany nam już program, generujący błąd polegający na próbie wykonania niedozwolonego dzielenia przez zero. Tym razem jednak zamiast wyjątku klasy #TKVJOGVKE ZEGRVKQP przechwytujemy wyjątek klasy nadrzędnej 4WPVKOG ZEGRVKQP. Co więcej, nic nie stoi na przeszkodzie, aby przechwycić wyjątek jeszcze ogólniejszy, czyli wyjątek klasy nadrzędnej do 4WPVKOG ZEGRVKQP. Jak widać na rysunku 4.9, byłaby to klasa ZEGRVKQP. Przechwytywanie wielu wyjątków W jednym bloku VT[ECVEJ można przechwytywać wiele wyjątków. Konstrukcja taka zawiera wtedy jeden blok VT[ i wiele bloków ECVEJ. Schematycznie wygląda ona następująco: VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM _ ECVEJ -NCUC9[LæVMWKFGPV[HKMCVQT9[LæVMW ] QDUđWICY[LæVMW _ ECVEJ -NCUC9[LæVMWKFGPV[HKMCVQT9[LæVMW ] QDUđWICY[LæVMW _  FCNUGDNQMKECVEJ  ECVEJ -NCUC9[LæVMWPKFGPV[HKMCVQT9[LæVMWP ] QDUđWICY[LæVMWP _ Po wygenerowaniu wyjątku jest sprawdzane, czy jest on klasy -NCUC9[LCVMW, jeśli tak — są wykonywane instrukcje obsługi tego wyjątku i blok VT[ECVEJ jest opuszczany. Jeżeli jednak wyjątek nie jest klasy -NCUC9[LCVMW, jest sprawdzane, czy jest on klasy -NCUC9[LæVMW itd. 166 Praktyczny kurs Java Przy tego typu konstrukcjach należy jednak pamiętać o hierarchii wyjątków, nie jest bowiem obojętne, w jakiej kolejności będą one przechwytywane. Ogólna zasada jest taka, że nie ma znaczenia kolejność, o ile wszystkie wyjątki są na jednym poziomie hierarchii. Jeśli jednak przechwytujemy wyjątki z różnych poziomów, najpierw muszą to być wyjątki bardziej szczegółowe, czyli stojące niżej w hierarchii, a dopiero po nich wyjątki bardziej ogólne, czyli stojące wyżej w hieriarchii. Nie można zatem najpierw przechwycić wyjątku 4WPVKOG ZEGRVKQP, a dopiero nim wyjątku #TKVJOGVKE ZEGRVKQP (por. rysunek 4.9), gdyż skończy się to błędem kompi- lacji. Jeśli więc dokonamy próby kompilacji przykładowego programu przedstawionego na listingu 4.11, efektem będą komunikaty widoczne na riysunku 4.10. Listing 4.11. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] VT[] KPVNKEDC _ ECVEJ 4WPVKOG ZEGRVKQPG ] 5[UVGOQWVRTKPVNP G  _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP G  _ _ _ Rysunek 4.10. Błędna hierarchia wyjątków powoduje błąd kompilacji Dzieje się tak dlatego, że (można powiedzieć) błąd bardziej ogólny zawiera już w sobie błąd bardziej szczegółowy. Jeśli zatem przechwytujemy najpierw wyjątek 4WPVKOG ZEGRVKQP, to tak jak byśmy przechwycili już wyjątki wszystkich klas dziedzi- czących z 4WPVKOG ZEGRVKQP. Dlatego też kompilator protestuje. Kiedy jednak może przydać się sytuacja, że najpierw przechwytujemy wyjątek szcze- gółowy, a potem dopiero ogólny? Otóż, wtedy, kiedy chcemy w specyficzny sposób zareagować na konkretny typ wyjątku, a wszystkie pozostałe z danego poziomu hie- rarchii obsłużyć w identyczny, standardowy sposób. Taka przykładowa sytuacja jest przedstawiona na listingu 4.12. Rozdział 4. ♦ Wyjątki Listing 4.12. 167 RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] 2WPMVRWPMVPWNN KPVNKEDC VT[] NKEDC RWPMVZNKEDC _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 0KGRTCYKFđQYCQRGTCELCCT[VOGV[EPC  5[UVGOQWVRTKPVNP G  _ ECVEJ ZEGRVKQPG ] 5[UVGOQWVRTKPVNP $đæFQIÎNP[  5[UVGOQWVRTKPVNP G  _ _ _ Zostały zadeklarowane dwie zmienne: pierwsza typu 2WPMV o nazwie RWPMV oraz druga typu KPV o nazwie NKEDC. Zmiennej RWPMV została przypisana wartość pusta PWNN, nie został zatem utworzony żaden obiekt klasy 2WPMV. W bloku VT[ są wykonywane dwie błędne instrukcje. Pierwsza z nich to znane nam z poprzednich przykładów dzielenie przez zero. Druga instrukcja z bloku VT[ to z kolei próba odwołania się do pola Z nie- istniejącego obiektu klasy 2WPMV (przecież zmienna RWPMV zawiera wartość PWNN). Ponie- waż chcemy w sposób niestandardowy zareagować na błąd arytmetyczny, najpierw przechwytujemy błąd typu #TKVJOGVKE ZEGRVKQP i, w przypadku kiedy wystąpi, wyświe- tlamy na ekranie napis 0KGRTCYKFđQYCQRGTCELC CT[VOGV[EPC. W drugim bloku ECVEJ przechwytujemy wszystkie inne możliwe wyjątki, w tym także wyjątek 0WNN2QKPVGT å ZEGRVKQP występujący, kiedy próbujemy wykonać operacje na zmiennej obiektowej, która zawiera wartość PWNN. Po uruchomieniu kodu z listingu 4.12 na ekranie pojawi się zgłoszenie tylko pierwszego błędu. Dzieje się tak dlatego, że po jego wystąpieniu blok VT[ został przerwany, a ste- rowanie zostało przekazane blokowi ECVEJ. Czyli jeśli w bloku VT[ któraś z instrukcji spowoduje wygenerowanie wyjątku, dalsze instrukcje z bloku VT[ nie zostaną wykonane. Nie miała więc szansy zostać wykonana nieprawidłowa instrukcja RWPMVZNKEDC. Jeśli jednak usuniemy wcześniejsze dzielenie przez zero, przekonamy się, że i ten błąd zostanie przechwycony przez drugi blok ECVEJ, a na ekranie pojawi się stosowny komu- nikat (rysunek 4.11). Rysunek 4.11. Odwołanie do pustej zmiennej obiektowej zostało wychwycone przez drugi blok catch 168 Praktyczny kurs Java Zagnieżdżanie bloków try...catch Bloki VT[ECVEJ można zagnieżdżać. To znaczy, że w jednym bloku przechwytują- cym wyjątek : może istnieć drugi blok, który będzie przechwytywał wyjątek ;. Sche- matycznie taka konstrukcja wygląda następująco: VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM _ ECVEJ 6[R9[LæVMWKFGPV[HKMCVQT9[LæVMW ] QDUđWICY[LæVMW _ _ ECVEJ 6[R9[LæVMWKFGPV[HKMCVQT9[LæVMW ] QDUđWICY[LæVMW _ Zagnieżdżenie takie może być wielopoziomowe, czyli w już zagnieżdżonym bloku VT[ można umieścić kolejny blok VT[, choć w praktyce takich piętrowych konstrukcji zazwyczaj się nie stosuje. Zwykle nie ma takiej potrzeby. Maksymalny poziom takiego bezpośredniego zagnieżdżenia z reguły nie przekracza dwóch poziomów. Aby na prak- tycznym przykładzie pokazać taką dwupoziomową konstrukcję, zmodyfikujemy przy- kład z listingu 4.12. Zamiast obejmowania jednym blokiem VT[ dwóch instrukcji powo- dujących błąd, zastosujemy zagnieżdżenie, tak jak jesit to widoczne na listingu 4.13. Listing 4.13. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] 2WPMVRWPMVPWNN KPVNKEDC VT[] VT[] NKEDC _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 0KGRTCYKFđQYCGQRGTCELCCT[VOGV[EPC  5[UVGOQWVRTKPVNP 2T[RKUWLúOKGPPGLNKEDCYCTVQħè  NKEDC _ RWPMVZNKEDC _ ECVEJ ZEGRVKQPG ] 5[UVGOQWVRTKPVNP $đæFQIÎNP[  5[UVGOQWVRTKPVNP G  _ _ _ Rozdział 4. ♦ Wyjątki 169 Podobnie jak w poprzednim przypadku, deklarujemy dwie zmienne: RWPMV klasy 2WPMV oraz NKEDC typu KPV. Zmiennej RWPMV przypisujemy wartość pustą PWNN. W wewnętrznym bloku VT[ próbujemy wykonać nieprawidłowe dzielenie przez zero i przechwytujemy wyjątek #TKVJOGVKE ZEGRVKQP. Jeśli on wystąpi, zmienna NKEDC otrzymuje domyślną wartość równą , dzięki czemu można wykonać kolejną operację, czyli próbę przypi- sania polu Z obiektu RWPMV wartości zmiennej NKEDC. Rzecz jasna, przypisanie takie nie może zostać wykonane, gdyż zmienna RWPMV jest pusta, jest zatem generowany wyjątek 0WNN2QKPVGT ZEGRVKQP, który jest przechwytywany przez zewnętrzny blok VT[. Widać więc, że zagnieżdżanie bloków VT[ może być przydatne, choć warto zauważyć, że identyczny efekt można osiągnąć, korzystając również z niezagnieżdżonej postaci instrukcji VT[ECVEJ (por. ćwiczenie 21.3). Ćwiczenia do samodzielnego wykonania 21.1. Popraw kod z listingu 4.11 tak, aby przechwytywanie wyjątków odbywało się w prawidłowej kolejności. 21.2. Zmodyfikuj kod z listingu 4.12 tak, aby zostały zgłoszone oba typy błędów: #TKVJOGVKE ZEGRVKQP oraz 0WNN2QKPVGT ZEGRVKQP. 21.3. Zmodyfikuj kod z listingu 4.5 w taki sposób, aby usunąć zagnieżdżenie bloków VT[ECVEJ, nie zmieniając jednak efektów działania programu. Lekcja 22. Własne wyjątki Wyjątki możemy przechwytywać, aby zapobiec niekontrolowanemu zakończeniu programu w przypadku wystąpienia błędu. Tą technikę poznaliśmy w lekcjach 20. i 21. Okazuje się jednak, że można je również samemu zgłaszać, a także że można tworzyć nowe, nieistniejące wcześniej klasy wyjątków. Tej właśnie tematyce jest poświęcona bieżąca, 22., lekcja. Zgłoś wyjątek Wiemy, że wyjątki są obiektami. Skoro tak, zgłoszenie własnego wyjątku będzie po- legało po prostu na utworzeniu nowego obiektu klasy opisującej wyjątek. Dokładniej za pomocą instrukcji PGY należy utworzyć nowy obiekt klasy, która pośrednio lub bezpo- średnio dziedziczy z klasy 6JTQYCDNG. W najbardziej ogólnym przypadku będzie to klasa ZEGRVKQP. Tak utworzony obiekt musi stać się parametrem instrukcji VJTQY. Jeśli zatem gdziekolwiek w pisanym przez nas kodzie chcemy zgłosić wyjątek ogólny, wystarczy, że napiszemy: VJTQYPGY ZEGRVKQP  W specyfikacji metody musimy jednak zaznaczyć, że będziemy w niej zgłaszać wyjątek danej klasy. Robimy to za pomocą instrukcji VJTQYU, w ogólnej postaci: URGE[HKMCVQTAFQUVGRW=UVCVKE?=HKPCN?V[RAYCTCECP[PCYCAOGVQF[ CTIWOGPV[ VJTQYU-NCUC9[LæVMW-NCUC9[LæVMW-NCUC9[LCVMWP ] VTGħèOGVQF[ _ 170 Praktyczny kurs Java Zobaczmy, jak to wygląda w praktyce. Załóżmy, że mamy klasę /CKP, a w niej metodę OCKP. Jedynym zadaniem tej metody będzie zgłoszenie wyjątku klasy ZEGRVKQP. Klasa taka jest widoczna na listingu 4.14. Listing 4.14. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? VJTQYU ZEGRVKQP ] VJTQYPGY ZEGRVKQP  _ _ W deklaracji metody OCKP zaznaczyliśmy, że może ona generować wyjątek klasy ZEGRVKQP poprzez użycie instrukcji VJTQYU ZEGRVKQP. W ciele metody OCKP została natomiast wykorzystana instrukcja VJTQY, która jako parametr otrzymała nowy obiekt klasy ZEGRVKQP. Po uruchomieniu takiego programu na ekranie zobaczymy widok zaprezentowany na rysunku 4.12. Jest to najlepszy dowód, że faktycznie udało nam się zgłosić wyjątek. Rysunek 4.12. Zgłoszenie wyjątku klasy Exception Utworzenie obiektu wyjątku nie musi mieć miejsca bezpośrednio w instrukcji VJTQY, można utworzyć go wcześniej, przypisać zmiennej obiektowej i dopiero tę zmienną wykorzystać jako parametr dla VJTQY. Czyli zamiast pisać: VJTQYPGY ZEGRVKQP  możemy równie dobrze zastosować konstrukcję: ZEGRVKQPGZEGRVKQPPGY ZEGRVKQP  VJTQYGZEGRVKQP W obu przedstawionych przypadkach efekt będzie identyczny, najczęściej korzystamy jednak z pierwszego zaprezentowanego sposobu. Jeśli chcemy, aby zgłaszany wyjątek otrzymał komunikat, należy przekazać go jako parametr konstruktora klasy ZEGRVKQP, czyli napiszemy wtedy: VJTQYPGY ZEGRVKQP MQOWPKMCV  lub: ZEGRVKQPGZEGRVKQPPGY ZEGRVKQP MQOWPKMCV  VJTQYGZEGRVKQP Rozdział 4. ♦ Wyjątki 171 Oczywiście, można tworzyć obiekty wyjątków klas dziedziczących z ZEGRVKQP. Przykładowo: jeśli sami wykryjemy próbę dzielenia przez zero, być może zechcemy wygenerować nasz wyjątek, nie czekając, aż zgłosi go maszyna wirtualna. Spójrzmy na listing 4.15. Listing 4.15. RWDNKE ENCUU ZCORNG ] RWDNKEFQWDNGH KPVNKEDCKPVNKEDC ] KH NKEDC VJTQYPGY#TKVJOGVKE ZEGRVKQP  KGNGPKGGRTGGTQ NKEDC  NKEDC  TGVWTPNKEDCNKEDC _ RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ]  ZCORNGGZCORNGPGY ZCORNG  KPVY[PKMGZCORNGH   5[UVGOQWVRTKPVNP 9[PKMRKGTYUGIQFKGNGPKCG Y[PKM  Y[PKMGZCORNGH   5[UVGOQWVRTKPVNP 9[PKMFTWIKGIQFKGNGPKC Y[PKM  _ _ W klasie ZCORNG jest zdefiniowana metoda H, która przyjmuje dwa argumenty typu KPV. Ma ona zwracać wynik dzielenia wartości przekazanej w argumencie NKEDC przez wartość przekazaną w argumencie NKEDC. Jest zatem jasne, że NKEDC nie może mieć wartości zero. Sprawdzamy to, wykorzystując instrukcję warunkową KH. Jeśli okaże się, że NKEDC ma jednak wartość zero, za pomocą instrukcji VJTQY wyrzucamy nowy wyjątek klasy #TKVJOGVKE ZEGRVKQP. W konstruktorze klasy przekazujemy komunikat informujący o dzieleniu przez zero. Podajemy w nim wartości argumentów metody H, tak by łatwo można było stwierdzić, jakie parametryi spowodowały błąd. W celu przetestowania działania metody H w klasie ZCORNG pojawiła się również metoda OCKP. Tworzymy w niej nowy obiekt klasy ZCORNG i przypisujemy go zmiennej o nazwie GZCORNG. Następnie dwukrotnie wywołujemy metodę H, raz przekazując jej argumenty równe  i , drugi raz przekazując jej argumenty równe  i . Spodziewamy się, że w drugim przypadku program zgłosi wyjątek #TKVJOGVKE ZEGRVKQP ze zdefiniowanym przez nas komunikatem. Faktycznie program zachowa się w taki właśnie sposób, co jest widoczne na rysunku 4.13. Rysunek 4.13. Zgłoszenie własnego wyjątku klasy ArithmeticException 172 Praktyczny kurs Java Ponowne zgłoszenie przechwyconego wyjątku Wiemy już, jak przechwytywać wyjątki oraz jak samemu zgłaszać wystąpienie wyjątku. To pozwoli nam zapoznać się z techniką ponownego zgłaszania (potocznie: wyrzuca- nia) już przechwyconego wyjątku. Jak pamiętamy, bloki VT[ECVEJ można zagnież- dżać bezpośrednio, a także stosować je w przypadku kaskadowo wywoływanych metod. Jeśli jednak na którymkolwiek poziomie przechwytywaliśmy wyjątek, jego obsługa ulegała zakończeniu. Nie zawsze jest to korzystne zachowanie, czasami istnieje potrzeba, aby po wykonaniu naszego bloku obsługi wyjątek nie był niszczony, ale przekazywany dalej. Aby osiągnąć takie zachowanie, musimy zastosować instrukcję VJTQY. Schema- tycznie wyglądałoby to następująco: VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM _ ECVEJ V[R6[LæVMWKFGPV[HKMCVQT9[LæVMW ] KPUVTWMELGQDUđWIWLæEGU[VWCELúY[LæVMQYæ VJTQYKPFGV[HKMCVQT9[LæVMW _ Listing 4.16 przedstawia, jak taka sytuacja wygląda w praktyce. W bloku VT[ jest wykonywana niedozwolona instrukcja dzielenia przez zero. W bloku ECVEJ najpierw wyświetlamy na ekranie informację o przechwyceniu wyjątku, a następnie za pomocą instrukcji VJTQY ponownie wyrzucamy (zgłaszamy) przechwycony już wyjątek. Ponieważ w programie nie ma już innego bloku VT[ECVEJ, który mógłby przechwycić ten wyjątek, zostanie on obsłużony standardowo przez maszynę wirtualną. Dlatego też na ekranie zobaczymy widok zaprezentowany na rysunku 4.14i. Listing 4.16. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] VT[] KPVNKEDC _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 6WY[LæVGMQUVCđRTGGEJY[EQP[  VJTQYG _ _ _ Rysunek 4.14. Ponowne zgłoszenie raz przechwyconego wyjątku Rozdział 4. ♦ Wyjątki 173 W przypadku zagnieżdżonych bloków VT[ sytuacja wygląda analogicznie. 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ć oczywiście zgłoszony kolejny raz itd. Jest to zobrazowane na listingu 4.17. Listing 4.17. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ] VWFQYQNPGKPUVTWMELG VT[] VWFQYQNPGKPUVTWMELG VT[] KPVNKEDC _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 6WY[LæVGMQUGVCđRTGEJY[EQP[RKGTYU[ TC  VJTQYG _ _ ECVEJ #TKVJOGVKE ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 6WY[LæVGMQUVCđRTGEJY[EQP[FTWIKTC  VJTQYG _ _ _ Mamy tu dwa zagnieżdżone bloki VT[. W bloku wewnętrznym zostaje wykonana nie- prawidłowa instrukcja dzielenia przez zero. Zostaje ona w tym bloku przechwycona, a na ekranie zostaje wyświetlony komunikat o pierwszym przechwyceniu wyjątku. Następnie wyjątek jest ponownie zgłaszany. W bloku zewnętrznym następuje drugie przechwycenie, wyświetlenie drugiego komunikatu oraz kolejne zgłoszenie wyjątku. Ponieważ nie istnieje trzeci blok VT[ECVEJ, ostatecznie wyjątek jest obsługiwany przez maszynę wirtualną. Po uruchomieniu zobaczymy widok zaprezentowany na rysunku 4.15. Rysunek 4.15. Przechwytywanie i ponowne zgłaszanie wyjątków W identyczny sposób będą zachowywały się wyjątki w przypadku kaskadowego wywo- ływania metod. Z sytuacją tego typu mieliśmy do czynienia w przypadku przykładu z listingu 4.8. W klasie ZCORNG były wtedy zadeklarowane cztery metody: OCKP, H, I, J. Metoda OCKP wywoływała metodę H, ta z kolei metodę I, a metoda I metodę J. W każdej 174 Praktyczny kurs Java z metod znajdował się blok VT[ECVEJ, jednak zawsze działał tylko ten najbliższy miejsca wystąpienia wyjątku (por. lekcja 20.). Zmodyfikujemy więc kod z listingu 4.8 tak, aby za każdym razem wyjątek był po przechwyceniu ponownie zgłaszany. Kod realizujący to zadanie jest przedstawiony na listinigu 4.18. Listing 4.18. RWDNKE ENCUU ZCORNG ] RWDNKEXQKFH ] VT[] I  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCH  VJTQYG _ _ RWDNKEXQKFI ] VT[] J  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCI  VJTQYG _ _ RWDNKEXQKFJ ] KPV=?VCDPGYKPV=? VT[] VCD=? _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCJ  VJTQYG _ _ RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ]  ZCORNGGZPGY ZCORNG  VT[] GZH  _ ECVEJ #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 9[LæVGMOGVQFCOCKP  VJTQYG _ _ _ Rozdział 4. ♦ Wyjątki 175 Wszystkie wywołania metod pozostały niezmienione, w każdym bloku ECVEJ została natomiast dodana instrukcja VJTQY ponownie zgłaszająca przechwycony wyjątek. Ry- sunek 4.16 pokazuje efekty uruchomienia przedstawionego kodu. Widać wyraźnie, jak wyjątek jest propagowany po wszystkich metodach, począwszy od metody J a skoń- czywszy na metodzie OCKP. Ponieważ w bloku VT[ECVEJ metody OCKP jest on ponow- nie zgłaszany, na ekranie jest także widoczna reakcija maszyny wirtualnej. Rysunek 4.16. Kaskadowe przechwytywanie wyjątków Tworzenie własnych wyjątków Programując w Javie, nie musimy zdawać się na wyjątki systemowe, które dostajemy wraz z JDK. Nic nie stoi na przeszkodzie, aby tworzyć własne klasy wyjątków. Wystar- czy więc, że napiszemy klasę pochodną pośrednio lub bezpośrednio z klasy 6JTQYCDNG, a będziemy mogli wykorzystywać ją do zgłaszania naszych własnych wyjątków. W prak- tyce jednak wyjątki wyprowadzamy z klasy ZEGRVKQP i klas od niej pochodnych. Klasa taka w najprostszej postaci będzie miała postać: RWDNKE ENCUUPCYCAMNCU[GZVGPFU ZEGRVKQP ] VTGħèMNCU[ _ Przykładowo możemy utworzyć bardzo prostą klasę o nazwie )GPGTCN ZEGRVKQP (wyjątek ogólny) w postaci: RWDNKE ENCUU)GPGTCN ZEGRVKQPGZVGPFU ZEGRVKQP ] _ To w zupełności wystarczy. Nie musimy dodawać żadnych nowych pól i metod. Ta klasa jest pełnoprawną klasą obsługującą wyjątki, z której możemy korzystać w taki sam sposób, jak ze wszystkich innych klas opisujących wyjątki. Na listingu 4.19 jest widoczna przykładowa klasa OCKP, która generuje wyjątek )GPGTCN ZEGRVKQP. Listing 4.19. RWDNKE ENCUU/CKP ] RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? VJTQYU)GPGTCN ZEGRVKQP 176 Praktyczny kurs Java ] VJTQYPGY)GPGTCN ZEGRVKQP  _ _ W metodzie OCKP za pomocą instrukcji VJTQYU zaznaczamy, że metoda ta może zgłaszać wyjątek klasy )GPGTCN ZEGRVKQP, sam wyjątek zgłaszamy natomiast przez zastosowanie instrukcji VJTQY, dokładnie w taki sam sposób, jak we wcześniejszych przykładach. Na rysunku 4.17 jest widoczny efekt działania takiego programu, faktycznie zgłoszony został wyjątek nowej klasy: )GPGTCN ZEGRVKQP. Rysunek 4.17. Zgłaszanie własnych wyjątków Własne klasy wyjątków można wyprowadzać również z klas pochodnych od ZEGRVKQP. Moglibyśmy np. rozszerzyć klasę #TKVJOGVKE ZEGRVKQP o wyjątek zgłaszany wyłącznie wtedy, kiedy wykryjemy dzielenie przez zero. Klasę itaką nazwalibyśmy KXKFG$[ GTQ å ZEGRVKQP. Miałaby ona postać widoczną na listingu 4.20. Listing 4.20. RWDNKE ENCUU KXKFG$[ GTQ ZEGRVKQPGZVGPFU#TKVJOGVKE ZEGRVKQP ] _ Możemy teraz zmodyfikować program z listingu 4.15 tak, aby po wykryciu dzielenia przez zero był zgłaszany wyjątek naszego nowego typiu, czyli KXKFG$[ GTQ ZEGRVKQP. Klasa taka została przedstawiona na listingu 4.21. Listing 4.21. RWDNKE ENCUU ZCORNG ] RWDNKEFQWDNGH KPVNKEDCKPVNKEDC ] KH NKEDC VJTQYPGY KXKFG$[ GTQ ZEGRVKQP  TGVWTPNKEDCNKEDC _ RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ]  ZCORNGGZCORNGPGY ZCORNG  FQWDNGY[PKMGZCORNGH   5[UVGOQWVRTKPVNP 9[PKMRKGTYUGIQFKGNGPKCG Y[PKM  Rozdział 4. ♦ Wyjątki 177 Y[PKMGZCORNGH   5[UVGOQWVRTKPVNP 9[PKMFTWIKGIQFKGNGPKC YG[PKM  _ _ W stosunku do kodu z listingu 4.15 zmiany nie są duże, ograniczają się do zmiany typu zgłaszanego wyjątku w metodzie H. Zadaniem tej metody nadal jest zwrócenie wyniku dzielenia argumentu NKEDC przez argument NKEDC. W metodzie OCKP dwukrotnie wywołujemy metodę H, pierwszy raz z prawidłowymi danymi i drugi raz z danymi, które spowodują wygenerowanie wyjątku. Efekt działania przedstawionego kodu jest widoczny na rysunku 4.18. Rysunek 4.18. Zgłoszenie wyjątku DivideByZeroException Zwróćmy jednak uwagę, że pierwotnie (listing 4.15) przy zgłaszaniu wyjątku para- metrem konstruktora był komunikat (czyli wartość typu 5VTKPI). Tym razem nie mo- gliśmy jej umieścić, gdyż nasza klasa KXKFG$[ GTQ ZEGRVKQP nie posiada konstruktora przyjmującego jako parametr obiektu typu 5VTKPI, a jedynie bezparametrowy kon- struktor domyślny. Aby zatem można było przekazywać nasze własne komunikaty, należy dopisać do klasy KXKFG$[ GTQ ZEGRVKQP odpowiedni konstruktor. Przyjmie ona wtedy postać widoczną na listingu 4.22. Listing 4.22. RWDNKE ENCUU KXKFG$[ GTQ ZEGRVKQPGZVGPFU#TKVJOGVKE ZEGRVKQP ] RWDNKE KXKFG$[ GTQ ZEGRVKQP 5VTKPIUVT ] UWRGT UVT  _ _ Teraz instrukcja VJTQY z listingu 4.21 mogłaby przyjąć np. następującą postaić: VJTQYPGY KXKFG$[ GTQ ZEGRVKQP  KGNGPKGRTGGTQ NKEDC  NKEDC  Sekcja finally Do bloku VT[ możemy dołączyć sekcję HKPCNN[, która będzie wykonana zawsze, nie- zależnie od tego, co będzie działo się w bloku VT[. Schematycznie taka konstrukcja będzie wyglądała następująco: 178 Praktyczny kurs Java VT[] KPUVTWMELGOQIæEGURQYQFQYCèY[LæVGM _ ECVEJ ] KPUVTWMELGUGMELKECVEJ _ HKPCNN[] KPUVTWMELGUGMELKHKPCNN[ _ Zgodnie z tym, co zostało napisane wcześniej, instrukcje sekcji HKPCNN[ są wykonywane zawsze, niezależnie od tego, czy w bloku VT[ wystąpi wyjątek, czy nie. Obrazuje to przykład z listingu 4.23, który jest oparty na kodziei z listingów 4.20 i 4.21. Listing 4.23. RWDNKE ENCUU ZCORNG ] RWDNKEFQWDNGH KPVNKEDCKPVNKEDC ] KH NKEDC VJTQYPGY KXKFG$[ GTQ ZEGRVKQP  KGNGPKGRTGGTQ NKEDC   NKEDC  TGVWTPNKEDCNKEDC _ RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ]  ZCORNGGZCORNGPGY ZCORNG  FQWDNGY[PKM VT[] Y[PKMGZCORNGH   _ ECVEJ KXKFG$[ GTQ ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 2TGEJY[EGPKGY[LæVMW  _ HKPCNN[] 5[UVGOQWVRTKPVNP 5GMELCHKPCNN[  _ VT[] Y[PKMGZCORNGH   _ ECVEJ KXKFG$[ GTQ ZEGRVKQPG ] 5[UVGOQWVRTKPVNP 2TGEJY[EGPKGY[LæVMWG  _ HKPCNN[] 5[UVGOQWVRTKPVNP 5GMELCHKPCNN[  _ _ _ Jest to znana nam klasa ZCORNG z metodą H wykonującą dzielenie przekazanych jej argumentów. Tym razem metoda H pozostała bez zmian w stosunku do wersji z listingu 4.21, czyli zgłasza błąd KXKFG$[ GTQ ZEGRVKQP. Zmodyfikowaliśmy natomiast metodę Rozdział 4. ♦ Wyjątki 179 OCKP. Oba wywołania metody zostały ujęte w bloki VT[ECVEJHKPCNN[. Pierwsze wywołanie nie powoduje powstania wyjątku, nie jest więc wykonywany pierwszy blok ECVEJ, jest natomiast wykonywany pierwszy blok HKPCNN[. Tym samym na ekranie pojawi się napis 5GMELCHKPCNN[. Drugie wywołanie metody H powoduje wygenerowanie wyjątku, zostaną zatem wyko- nane zarówno instrukcje bloku ECVEJ, jak i instrukcje bloku HKPCNN[. Na ekranie pojawią się zatem dwa napisy: 2TGEJY[EGPKG Y[LæVMW oraz 5GMELCHKPCNN[. Ostatecznie wyniki działania całego programu będzie taki, jak ten zaprezentowany na rysunku 4.19. Rysunek 4.19. Blok finally jest wykonywany niezależnie od tego, czy pojawi się wyjątek Sekcję HKPCNN[ można zastosować również w przypadku instrukcji, które nie powodują wygenerowania wyjątku. Stosujemy wtedy instrukcję VT[HKPCNN[ w postaci: VT[] KPUVTWMELG _ HKPCNN[] KPUVTWMELG _ Działanie jest takie samo jak w przypadku bloku VT[ECVEJHKPCNN[, to znaczy kod z bloku HKPCNN[ zostanie wykonany zawsze, niezależnie od tego, jakie instrukcje znajdą się w bloku VT[. Przykładowo: nawet jeśli w bloku VT[ znajdzie się instrukcja TGVWTP lub zostanie wygenerowany wyjątek, blok HKPCNN[ i tak zostanie wykonany. Obrazuje to przykład zaprezentowany na listingu 4.24. Listing 4.24. RWDNKE ENCUU ZCORNG ] RWDNKEKPVH ] VT[] TGVWTP _ HKPCNN[] 5[UVGOQWVRTKPVNP 5GMELCHKPCNN[H  _ _ RWDNKEXQKFH ] VT[] KPVNKEDC _ 180 Praktyczny kurs Java HKPCNN[] 5[UVGOQWVRTKPVNP 5GMELCHKPCNN[H  _ _ RWDNKEUVCVKEXQKFOCKP 5VTKPICTIU=? ]  ZCORNGGZCORNGPGY ZCORNG  GZCORNGH  GZCORNGH  _ _ Ćwiczenia do samodzielnego wykonania 22.1. Napisz klasę ZCORNG, w której zostaną zadeklarowane metody H i OCKP. W meto- dzie H napisz dowolną instrukcję generującą wyjątek 0WNN2QKPVGT ZEGRVKQP. W metodzie OCKP wywołaj metodę H, przechwyć wyjątek za pomocą bloku VT[ECVEJ. 22.2. Zmodyfikuj kod z listingu 4.17 tak, aby generowany, przechwytywany i ponownie zgłaszany był wyjątek #TTC[+PFGZ1WV1H$QWPFU ZEGRVKQP. 22.3. Napisz klasę o takim układzie metod, jak w przypadku klasy ZCORNG z listingu 4.18. W najbardziej zagnieżdżonej metodzie J wygeneruj wyjątek #TKVJOGVKE ZEGRVKQP. Przechwyć ten wyjątek w metodzie I i zgłoś wyjątek klasy nadrzędnej do #TKVJOGVKE å ZEGRVKQP, czyli 4WPVKOG ZEGRVKQP. Wyjątek ten przechwyć w metodzie H i zgłoś wyjątek nadrzędny do 4WPVKOG ZEGRVKQP, czyli ZEGRVKQP. Ten ostatni wyjątek prze- chwyć w klasie OCKP. 22.4. Napisz klasę wyjątku o nazwie 0GICVKXG8CNWG ZEGRVKQP oraz klasę ZCORNG, która będzie z niego korzystać. W klasie ZCORNG napisz metodę o nazwie H, przyjmującą dwa argumenty typu KPV. Metoda H powinna zwracać wartość będącą wynikiem odejmo- wania argumentu pierwszego od argumentu drugiego. W przypadku jednak, gdyby wynik ten był ujemny, powinien zostać zgłoszony wyjątek 0GICVKXG8CNWG ZEGRVKQP. Dopisz metodę OCKP, która przetestuje działanie metody H.
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Praktyczny kurs Java
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: