Java SE Laboratorium nr 4. Temat: Obsługa wyjątków i zdarzeń

Podobne dokumenty
Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Wyjątki Monika Wrzosek (IM UG) Programowanie obiektowe 180 / 196

Zad.30. Czy można utworzyć klasę, która implementuje oba interfejsy?

Języki i metody programowania Java INF302W Wykład 3 (część 1)

Wykład 8: Obsługa Wyjątków

WYJĄTKI. Jest ona jednak czasochłonna i prowadzi do duŝego zapotrzebowania na zasoby systemu.

Obsługa błędów za pomocą wyjątków. Paweł Motofa (140746)

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

Aplikacje w środowisku Java

Throwable. Wyjatek_1(int x_) { x = x_; } int podaj_x()

Programowanie Obiektowe Ćwiczenie 4

Programowanie obiektowe

Dawid Gierszewski Adam Hanasko

Wyjątki (exceptions)

Dokumentacja do API Javy.

Multimedia JAVA. Historia

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Programowanie obiektowe

Java podstawy jęyka. Wykład 2. Klasy abstrakcyjne, Interfejsy, Klasy wewnętrzne, Anonimowe klasy wewnętrzne.

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Aplikacje w środowisku Java

Praktyczny kurs Java

Programowanie obiektowe

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Rozdział 4 KLASY, OBIEKTY, METODY

Programowanie obiektowe

Klasy cd. Struktury Interfejsy Wyjątki

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

public - może być używana w kodzie poza klasą, jedna klasa ModyfikatorKlasy może być kombinacją wyrażeń:

Wykład 04. Programowanie obiektowe. Maciej Wołoszyn 17 marca Spis treści

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

Programowanie obiektowe

Aplikacje w środowisku Java

Dziedziczenie. Streszczenie Celem wykładu jest omówienie tematyki dziedziczenia klas. Czas wykładu 45 minut.

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Język C++ wykład VIII

Wprowadzanie danych z klawiatury. Wyjątki związane z wprowadzaniem danych, przekroczeniem rozmiaru tablicy, dzieleniem przez zero itd.

TEMAT : KLASY DZIEDZICZENIE

Marcin Luckner Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Programowanie w Internecie. Java

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Programowanie obiektowe

PARADYGMATY PROGRAMOWANIA Wykład 4

Dziedziczenie. Tomasz Borzyszkowski

Programowanie obiektowe

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

Podstawy i języki programowania

Programowanie obiektowe

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Programowanie obiektowe

Klasy abstrakcyjne, interfejsy i polimorfizm

Obsługa wyjątków. Rysunek 2-4 Hierarchia dziedziczenia klas wyjątków

Język JAVA podstawy. Wykład 4, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Efekty uboczne błędów

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Mechanizm dziedziczenia

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Wykład 8: klasy cz. 4

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Java - wprowadzenie. Programowanie Obiektowe Mateusz Cicheński

PHP 5 język obiektowy

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Platformy Programistyczne Podstawy języka Java

Klasy abstrakcyjne i interfejsy

Platformy Programistyczne Wykład z Javy dla zaawansowanych

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

1. Co będzie wynikiem wykonania poniŝszych instrukcji? g2d.gettransform().scale(1, -1); g2d.gettransform().translate(4, -8); g2d.drawline(4, 0, 4, 4);

Aplikacje Internetowe. Najprostsza aplikacja. Komponenty Javy. Podstawy języka Java

Język JAVA podstawy. wykład 2, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Języki i metody programowania Java. Wykład 2 (część 2)

Wykład 7: Pakiety i Interfejsy

Klasy i obiekty cz II

Programowanie obiektowe

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

Programowanie komputerowe. Zajęcia 7

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Czym są właściwości. Poprawne projektowanie klas

Obsługa wyjątków. Język C++ WW12

Sesje, ciasteczka, wyjątki. Ciasteczka w PHP. Zastosowanie cookies. Sprawdzanie obecności ciasteczka

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

1. Co można powiedzieć o poniższym kodzie? public interface I { void m1() {}; static public void m2() {}; void abstract m3();

1 Podstawy c++ w pigułce.

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

Materiały do zajęć III

Konwencje obsługi błędów

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Java. Leksykon kieszonkowy. Wydanie II

Dziedziczenie. dr Jarosław Skaruz

Transkrypt:

Java SE Laboratorium nr 4 Temat: Obsługa wyjątków i zdarzeń 1

1. Definicja i idea I. Obsługa wyjątków 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 wprowadzone 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ątków, który pozwala na przechwytywanie błędów. Wyjątek w języku Java to obiekt, który opisuje pewną sytuację błędną lub nieprawidłową wyjątkową. Jest to obiekt odpowiedniego typu, tj. obiekt klasy Throwable lub jej dowolnej podklasy. Wyjątki dzielą się na dwa rodzaje: kontrolowane i niekontrolowane. Kontrolowane to takie które musimy deklarować i obsługiwać. Wyjątki niekontrolowane także możemy obsługiwać, ale nie musimy. Wyjątki niekontrolowane to instancje klas Error i RuntimeException oraz ich dowolnych podklas. Wyjątki kontrolowane to instancje klas Throwable i Exception oraz ich podklas, z wyłączeniem podklas klas Error i RuntimeException. Error wskazuje na poważne błędy, których poprawna aplikacja nie powinna łapać. Większość tego typu błędów dotyczy sytuacji wyjątkowych - nie koniecznie związanych z samym kodem programu. Pytanie: Czym jest Compile Error, a czym Runtime Exception? 2

2. Blok try...catch Listing 1) Prezentacja prostego wyjątku: public class Listing1 { int[] tab = new int[10]; tab[10] = 5; Exception in thread "main" java.lang.arrayindexoutofboundsexception: 10 at Listing1.main(Listing1.java:7) 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 ograniczona. 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 try...catch. W najprostszej postaci wygląda on następująco: //instrukcje mogące spowodować wyjątek catch(typwyjątku identyfikatorwyjątku) { //obsługa wyjątku W nawiasach klamrowych występujących po słowie try umieszczamy instrukcję, która może spowodować wystąpienie wyjątku. W bloku występującym po catch umieszczamy kod, który ma zostać wykonany, kiedy wystąpi wyjątek. Listing 2) Poprzedni kod z blokiem try...catch: public class Listing2 { int[] tab = new int[10]; tab[10] = 5; catch(arrayindexoutofboundsexception e) { System.out.println("Nieprawidłowy indeks tablicy," + " wyjątek: " + e); 3

Nieprawidłowy indeks tablicy, wyjątek: java.lang.arrayindexoutofboundsexception: 10 W jednym bloku try...catch można przechwytywać wiele wyjątków. Konstrukcja taka zawiera wtedy jeden blok try i wiele bloków catch. Schematycznie wygląda ona następująco: //instrukcje mogące spowodować wyjątek catch(klasawyjątku1 identyfikatorwyjątku1) { //obsługa wyjątku 1 catch(klasawyjątku2 identyfikatorwyjątku2) { //obsługa wyjątku 2 /*... dalsze bloki catch... */ catch(klasawyjątkun identyfikatorwyjątkun) { //obsługa wyjątku n Po wygenerowaniu wyjątku jest sprawdzane, czy jest on klasy 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, jest sprawdzane, czy jest on klasy KlasaWyjątku2 itd. 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 hierarchii. Biorąc pod uwagę powyższą kwestię, możemy ustalić w bloku try...catch odpowiednik else lub default (czyli która klasa wyjątku powinna być ostatnim blokiem catch): - klasa wyżej w hierarchii, będąca ogólnym przypadkiem reszty catchy, - klasa Exception od której pochodzi reszta wyjątków. 4

Listing 3) Ukazanie hierarchii wyjątków: public class Listing3 { int[] tab = new int[10]; tab[10] = 5; catch(exception e) { System.out.println("Najbardziej ogólny wyjątek " + "(przykład else), wyjątek: " + e); catch(arrayindexoutofboundsexception e) { System.out.println("Nieprawidłowy indeks tablicy, " + "wyjątek: " + e); Exception in thread "main" java.lang.error: Unresolved compilation problem: Unreachable catch block for ArrayIndexOutOfBoundsException. It is already handled by the catch block for Exception at Listing3.main(Listing3.java:11) 3. Sekcja finally Do bloku try...catch możemy dołączyć sekcję finally, która będzie wykonana zawsze, niezależnie od tego, co będzie działo się w bloku wyjątków. Schematycznie taka konstrukcja będzie wyglądała następująco: //instrukcje mogące spowodować wyjątek catch(typwyjątku identyfikatorwyjątku) { //obsługa wyjątku finally { //instrukcje sekcji finally Listing 4) Użycie bloku finally: public class Listing4 { int[] tab = new int[10]; tab[10] = 5; catch(arrayindexoutofboundsexception e) { System.out.println("Nieprawidłowy indeks tablicy, " + "wyjątek: " + e); finally { System.out.println("Wykonuję operacje sekcji finally."); 5

Nieprawidłowy indeks tablicy, wyjątek: java.lang.arrayindexoutofboundsexception: 10 Wykonuję operacje sekcji finally. Sekcję finally można zastosować również w przypadku instrukcji, które nie powodują wygenerowania wyjątku. Stosujemy wtedy instrukcję try...finally w postaci: //instrukcje do wykonania finally { //instrukcje sekcji finally Działanie jest takie samo jak w przypadku bloku try...catch...finally, to znaczy kod z bloku finally zostanie wykonany zawsze, niezależnie od tego, jakie instrukcje znajdą się w bloku try. Przykładowo: nawet jeśli w bloku try znajdzie się instrukcja return lub zostanie wygenerowany wyjątek, blok finally i tak zostanie wykonany. 4. 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. Wystarczy więc, że napiszemy klasę pochodną pośrednio lub bezpośrednio z klasy Throwable, a będziemy mogli wykorzystać ją do zgłaszania naszych własnych wyjątków. W praktyce jednak wyjątki wyprowadzamy z klasy Exception i klas od niej pochodnych. Klasa taka w najprostszej postaci będzie miała postać: public class NazwaKlasy extends Exception { //treść klasy Przykładowo możemy utworzyć bardzo prostą klasę o nazwie GeneralException w postaci: public class GeneralException extends Exception { 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. 6

Listing 5) Użycie własnego wyjątku (lekko rozbudowanego): public class GeneralException extends Exception{ public GeneralException() {; public GeneralException(String msg) { super(msg); ; public class Listing5 { throw new GeneralException("Mój własny błąd"); catch(generalexception e){ System.err.println("Przechwyciłem mój wyjątek: " + e); e.printstacktrace(); Przechwyciłem mój wyjątek: GeneralException: Mój własny błąd GeneralException: Mój własny błąd at Listing5.main(Listing5.java:6) Ponieważ wyjątek to obiekt jak wszystkie inne, proces rozbudowy własnych klas wyjątków można posunąć jeszcze dalej. Jednak należy pamiętać, że cała ta "dekoracja" może zostać pominięta przez programistę wykorzystującego ten pakiet z zewnątrz, gdyż może on jedynie sprawdzać, czy w metodzie wyrzucono wyjątek i nic poza tym (w ten sposób używa się większości wyjątków z biblioteki Javy). 5. Rejestrowanie wyjątków Wyjątki można także rejestrować (logować) przy użyciu mechanizmów z biblioteki java.util.logging. Daje nam to możliwość tworzenia zapisu kolejnych zdarzeń opisujący działania użytkownika lub programu (w tym przypadku wyjątków). Cała infrastruktura rejestracji jest wbudowana w wyjątek, dzięki czemu całość działa bez interwencji ze strony programisty-klienta. Najczęściej przychodzi nam przechwytywać i rejestrować cudze klasy wyjątków, co wymaga wygenerowania wpisu do logu w ramach procedury obsługi wyjątku. 7

Listing 6) Rejestrowanie wyjątków domyślnych i własnych: import java.io.printwriter; import java.io.stringwriter; import java.util.logging.logger; public class Listing6 { private static Logger logger = Logger.getLogger("Listing6"); static void logexception(exception e){ StringWriter sw = new StringWriter(); e.printstacktrace(new PrintWriter(sw)); logger.severe(sw.tostring()); int[] tab = new int[10]; tab[10] = 5; catch(arrayindexoutofboundsexception e) { logexception(e); throw new GeneralException("Mój własny błąd"); catch(generalexception e){ logexception(e); mar 12, 2014 2:03:13 PM Listing6 logexception SEVERE: java.lang.arrayindexoutofboundsexception: 10 at Listing6.main(Listing6.java:19) mar 12, 2014 2:03:13 PM Listing6 logexception SEVERE: GeneralException: Mój własny błąd at Listing6.main(Listing6.java:25) 6. RuntimeException Wyjątek RuntimeException (lub cokolwiek co po nim dziedziczy) jest specjalnym przypadkiem, ponieważ kompilator nie wymaga dla tych typów używania bloku try...catch. Założono bowiem, że te wyjątki mają reprezentować błędy programistyczne, takie jak: Błąd, którego nie można przewidzieć. Na przykład przekazanie referencji null z kodu, którego programista nie kontroluje. Błędy, które my, jako programiści, powinniśmy sami wykrywać we własnym kodzie (takie jak odwoływanie się poza rozmiar tablicy). Powodem tych wyjątków często stają się wyjątki zaliczające się do poprzedniego punktu. Widać tu, jaką olbrzymią zaletą jest w tym przypadku istnienie wyjątków: pomagają one w procesie testowania i usuwania błędów. 8

Listing 7) Własny wyjątek RuntimeException: public class GeneralException extends RuntimeException { public GeneralException() {; public GeneralException(String msg) { super(msg); ; public class Listing7 { throw new GeneralException("Mój własny błąd"); Exception in thread "main" GeneralException: Mój własny błąd at Listing6.main(Listing7.java:5) 7. Zgłaszanie wyjątków w własnych klasach W Javie wymagane jest informowanie programistów, wywołujących napisaną przez nas metodę, o wyjątkach, jakie mogą zostać przez nią zgłoszone. Jest to dobra zasada, ponieważ dzięki temu osoba wywołująca wie, co musi napisać, aby przechwycić wszystkie możliwe wyjątki. Oczywiście jeśli dostępny jest kod źródłowy, można go po prostu przejrzeć w poszukiwaniu instrukcji throw. Najczęściej jednak źródła bibliotek nie są dostarczane. Aby zapobiec temu problemowi składnia Javy dostarcza składnię (oraz wymusza jej stosowanie)zwaną specyfikacją wyjątków i jest częścią deklaracji metody, pojawiającą się po liście parametrów. Specyfikacja wyjątków wykorzystuje dodatkowo słowo kluczowe throws, po którym następuje lista wszystkich potencjalnych typów wyjątków. Przykładowa definicja metody może wyglądać następująco: void metoda() throws Wyjątek1, Wyjątek2, Wyjątek3 { Jeśli napiszemy: void metoda() { oznacza to, że żadne wyjątki nie są wyrzucane z tej metody (oprócz wyjątków typu RuntimeException). Nie można oszukać specyfikacji wyjątków - jeśli metoda powoduje wyjątki i nie obsługuje ich, kompilator wykryje to i zgłosi, że należy albo obsłużyć wyjątek, albo zaznaczyć w specyfikacji wyjątków, że ten wyjątek może być wyrzucony z metody. 9

Listing 8) Użycie specyfikacji wyjątków: public class MojaKlasa { public MojaKlasa() throws GeneralException { System.out.println("Kontruktor MojaKlasa"); protected void metodatestowa(int a) throws GeneralException{ System.out.println("Moja metodatestowa " + a); if(a!= 0) throw new GeneralException("a różne od zera"); public class Listing8 { MojaKlasa mk = null; //poniższa inicjalizacja wyrzuca błąd //mk = new MojaKlasa(); try{ mk = new MojaKlasa(); catch(generalexception e){ System.err.println("Wyjątek podczas tworzenia obiektu"); //poniższe użycie metody musi być w bloku try...catch try{ mk.metodatestowa(0); catch(generalexception e){ System.err.println("Wyjątek podczas używania metody1"); System.err.print(e); try{ mk.metodatestowa(-1); catch(generalexception e){ System.err.print("Wyjątek podczas używania metody2: "); System.err.print(e); Kontruktor MojaKlasa Moja metodatestowa 0 Moja metodatestowa -1 Wyjątek podczas używania metody2: GeneralException: a różne od zera W metodzie przeciążonej można zgłaszać jedynie te wyjątki, które zostały podane w specyfikacji jej wersji z klasy bazowej. Jest to użyteczne ograniczenie, ponieważ oznacza, że 10

kod, który działa dla klasy bazowej, będzie automatycznie działał z każdym obiektem dziedziczącym z klasy bazowej, włączając to prawidłową obsługę wyjątków. Powyższego ograniczenia wyjątków nie stosuje się do konstruktorów. Konstruktor z klasy dziedziczącej może zgłaszać co zechce, niezależnie od tego, co zgłasza konstruktor klasy bazowej. Jednak, ponieważ konstruktor klasy bazowej musi zostać wywołany w taki czy inny sposób, konstruktor klasy pochodnej musi zadeklarować wszystkie wyjątki konstruktora klasy bazowej. Konstruktor klasy pochodnej nie może przechwytywać wyjątków zgłaszanych przez konstruktor klasy bazowej. Listing 9) Ograniczenia wyjątków podczas dziedziczenia: public class MojaKlasa { public MojaKlasa() throws GeneralException { System.out.println("Kontruktor MojaKlasa"); protected void metodatestowa(int a) throws GeneralException{ System.out.println("Moja metodatestowa " + a); if(a!= 0) throw new GeneralException("a różne od zera"); public class MojaNowaKlasa extends MojaKlasa { /*poniższy konstruktor wyrzuca błąd public MojaNowaKlasa(){ */ public MojaNowaKlasa() throws GeneralException { super(); /*niepoprawne przeciążenie metody protected void metodatestowa(int a) throws IOException { */ protected void metodatestowa(int a) { System.out.println("Moja nowametodatestowa " + a); 11

8. Wskazówki przy używaniu wyjątków Wyjątków należy używać do: Naprawiania problemów na odpowiednim poziomie (należy unikać przechwytywania wyjątków, jeśli nie wiadomo co z nimi zrobić). Naprawienia problemu i ponownego wywołania metody, która spowodowała wyjątek. Wyjścia z sytuacji, która spowodowała wyjątek, i kontynuowania bez ponownego wywoływania szwankującej metody. Wygenerowania alternatywnego rozwiązania zamiast tego, które miała wyprodukować metoda. Zrobienia, co tylko się da w aktualnym kontekście, i zgłoszenia ponownie tego samego wyjątku do kontekstu nadrzędnego. Zrobienia, co tylko się da w aktualnym kontekście, i zgłoszenia innego wyjątku do kontekstu nadrzędnego. Zakończenia programu. Upraszczania (jeśli schemat obsługi wyjątków sprawia, że wszystko jest jeszcze bardziej skomplikowane, to jest on żmudny i irytujący w użyciu). Sprawiania, aby biblioteka i program były bezpieczniejsze (jest to inwestycja krótkoterminowa przy poprawianiu błędów oraz długofalowa dla poprawienia niezawodności aplikacji). Zadanie 1 public class Zadanie1 { Integer x = null; int liczba; liczba = 10 / 0; x = liczba; catch(exception e) { System.out.println("Błąd ogólny"); System.out.println(e); catch(arithmeticexception e) { System.out.println("Nieprawidłowa operacja arytmetyczna"); System.out.println(e); 1. Popraw kod z powyższego listingu tak, aby przechwytywanie wyjątków odbywało się w prawidłowej kolejności. 2. Dodaj obsługę błędu NullPointerException. 3. Zmodyfikuj kod tak, aby zostały zgłoszone oba typy błędów: ArithmeticException i NullPointerException. 4. Dodaj sekcję finally, która wyświetli napis "Finally" oraz wartość zmiennej 'liczba'. 12

Zadanie 2 1. Napisz kod generujący i przechwytujący wyjątek typu ArrayIndexOutOfBoundsException (indeks tablicy poza zakresem). 2. W sekcji catch dodaj rejestrowanie wyjątku. 3. Utwórz własną klasę wyjątków (dziedzicząc z klasy Exception). Napisz dla tej klasy konstruktor przyjmujący parametr String i zapamiętujący ten parametr wewnątrz obiektu. Napisz metodę, która wyświetla zapamiętany łańcuch. 4. Napisz klasę z metodą, która zgłasza wyjątek stworzony w poprzednim punkcie. Spróbuj go skompilować bez specyfikacji wyjątku, aby zobaczyć, co zrobi kompilator. Dodaj odpowiednią specyfikację wyjątku. Wypróbuj swoją klasę i jej wyjątki wewnątrz bloku try...catch. 5. Stwórz trzy nowe typy wyjątków (dziedziczące z wyjątku utworzonego w punkcie 3). Do klasy z punktu 4 dodaj metodę, która zgłasza wszystkie trzy. W metodzie main() wywołaj tę metodę, ale użyj pojedynczej sekcji catch, która przechwyci wszystkie trzy typy wyjątków. 6. Do klasy z punktu 4 dodaj dwie metody f() i g(). W g() zgłoś wyjątek nowego, zdefiniowanego przez ciebie typu. W f() wywołaj g(), przechwyć jej wyjątki i w sekcji catch zgłoś inny wyjątek (drugiego zdefiniowanego przez ciebie typu). Przetestuj swój kod w main(). 7. Stwórz trójpoziomową hierarchię wyjątków. Następnie stwórz klasę bazową A z metodą, która zgłasza wyjątek będący podstawą hierarchii. Odziedzicz B z A i przeciąż tę metodę tak, żeby zgłaszała wyjątek na drugim poziomie hierarchii. Powtórz to, dziedzicząc klasę C z B. W main () utwórz obiekt klasy C i zrzutuj go do A, a następnie wywołaj jego metodę. 13