Wyjątki – porady praktyczne

ByKamil

Wyjątki – porady praktyczne

Poprzedni wpis tworzenie własnych klas wyjątków.

Mogłoby się wydawać, że jest to najrozsądniejsze wyjście, gdyż Exception jako nadklasa wyłapie wszystkie możliwe sytuacje, które mogą się wydarzyć i nic nas nie zaskoczy. Ta pozorna wygoda może nas jednak wiele kosztować. Przy ustalaniu błędu dobrze mieć pewność, które dokładnie sytuacje są obsługiwane.

Dlaczego nie używać klasy Exception?

Poniżej postaramy się wymienić kilka powodów, dla których nie warto korzystać z ogólnej klasy Exception.

Wyłapywanie wszystkich błędów

Jeżeli spróbujemy przechwycić Exception musimy mieć świadomość, że wyłapiemy dosłownie wszystko co należy do tego poddrzewa. Niektóre wyjątkowe sytuacje obsługuje się w identyczny sposób, jednakże trzeba mieć świadomość, że w ten sposób wyłapiemy również te wyjątki, których nie chcemy. Jakie mogą być tego konsekwencje? Podobne jak w przypadku nie przechwycenia wyjątku – brak obsługi oraz zatrzymanie wątku.

Podobny problem może wyjść w przypadku dowolnego poddrzewa np. IOException. Jeśli dwie klasy wyjątków musimy obsłużyć w inny sposób należy to bezwzględnie zrobić.

Szczegółowa obsługa

Hierarchia dziedziczenia to drzewo, które prowadzi od ogółu do szczegółu. W związku z tym w najbardziej ogólnej klasie znajdują się tylko podstawowe metody, które muszą pasować do wszystkich wyjątków. Przeglądając oficjalną dokumentację Javy warto zwrócić uwagę na metody, które są dostarczone przez poszczególne klasy i porównać je z tymi z klasy wyżej położonymi w hierarchii dziedziczenia.

Ukrycie błędów, których nie powinniśmy obsługiwać (unchecked)

Jak wspominaliśmy wielokrotnie tego typu wyjątków nie obsługujemy, ani nie przechwytujemy, gdyż są one do opanowania przez odpowiedni kod. Np Klasa NullPointerException lub ArrayOutOfBoundException mogą być wywołane przez kolejno użyciu metody podczas, gdy zmienna wskazuje na wartość null lub przy próbie dostania się do tablicy indeksem większym niż jej rozmiar. Każdy z tych błędów powinien być odpowiednio zabezpieczony kodem, a nie wyjątkiem.

Hierarchia dziedziczenia widoczna na rysunku jasno pokazuje, że po klasie Exception dziedziczą także wyjątki typu RuntimeException. Przechwycenie tych wyjątków spowoduje jego „uśpienie” przez co trudniej może być go zlokalizować. Co gorsza czasami podczas testowania programu może wydawać się, że wszystko będzie działać w porządku i dopiero po dokładnym sprawdzeniu wyników okaże się, że istnieje jakiś błąd.

Hierarchia wyjątków w Javie

Hierarchia wyjątków w Javie

Metoda printStackTrace

Wiele programów, które zawierają blok try-catch zawiera przybliżony kod.

Metoda printStackTrace() jest zdefiniowana w klasie Throwable i jest ona dostępna w każdej klasie wyjątków.

Wywołanie tej metody w bloku catch nie jest kodem rozwiązującym problem powstały w bloku try. W przypadku niektórych aplikacji należy ją zastąpić właściwym algorytmem, który rozwiąże problem (choć nie zawsze jest to potrzebne). Wtedy może być bardzo przydatna w celach diagnostycznych, gdyż zwraca na ekran konsoli zrzut ze stosu wywołań (ang. stack trace).

Stos wywołań (stack trace)

Stos jest typem, który charakteryzuje się tym, że ostatni element dodany jest jako pierwszy zdejmowany (artykuł dokładniej opisujący kolejki LIFO). W związku z tym po wywołaniu metody printStackTrace() dostajemy odwróconą kolejność (pierwszy podany element jest tym, który spowodował wyjątek). Taki sposób pokazania błędu może pomóc zlokalizować powstały błąd. Nie zawsze jest on oczywisty i powodem może być zupełnie inny fragment niż ten, który akurat wywołał błąd.

Struktura stosu wywołań

Pierwsza linia zwraca nazwę klasy, której wyjątek został rzucony oraz informację o pakiecie. Kolejne linie zaczynają się od słowa at. Następnie wypisane są po kolei pakiet, klasa, metoda oraz w nawiasie plik, w którym znajduje się kod i numer linii w której jest wywołana metoda. Poniżej pokażemy przykładowy stos wywołań.

Jak pokazuje powyższy zrzut od końca w metodzie main została wywołana metoda getWezel, w której został rzucony wyjątek typu TreeIndexException.

About the author

Kamil editor