Java HR: Wyjątki – Exception i Error, checked i unchecked

Java HR: Wyjątki – Exception i Error, checked i unchecked

Tym razem wyjątkowy artykuł – wyjątki każdy programista zna i zapewne używa regularnie, jednak czym różnią się w Javie poszczególne ich rodzaje?

Czym jest wyjątek


Mechanizm wyjątków służy do obsługi błędów, które mogą wystąpić w czasie przebiegu programu. Jak sama nazwa wskazuje, wyjątek (exception) to odbiegnięcie od standardowego, zaplanowanego przebiegu programu. W Javie wyjątek reprezentowany jest przez obiekt klasy Throwable, który posiada zbiór pól i metod przydatnych do jego późniejszej analizy – oprócz swojej nazwy przechowuje takie informacje jak opis błędu (message) oraz stack trace, czyli zapis stosu wywołań, reprezentujący obecny stan programu.

Podział wyjątków w Javie


Hierarchia klas:

–Throwable
——Error
——Exception
———-Poszczególne wyjątki
———-RuntimeException
————–Poszczególne wyjątki

Wyjątki zgromadzone są w 3 podstawowych grupach.
Klasa Throwable dzieli się na dwie inne, dziedziczące po niej klasy – ErrorException. Po Exception z kolei dziedziczy RuntimeException oraz już bezpośrednio cały szereg poszczególnych wyjątków, takich jak IOException czy SQLException.

  • Error – obiekty rzucane automatycznie przez JVM, w momencie gdy program natrafi na krytyczny błąd w środowisku wykonawczym, którego nie można obsłużyć i z którego nie można programu już odratować.
    Przykłady: OutOfMemoryError, StackOverflowError
  • Exception – „klasyczne”, najzwyklejsze wyjątki. Konieczna jest ich obsługa (patrz niżej) i to najczęściej tę klasę będziemy rozszerzać tworząc własną klasę Throwable.
    Najczęściej dotyczą sytuacji, w której jest duża szansa, że błąd może wystąpić na skutek jakiejś zewnętrznej przyczyny – np. w systemie gospodarza zabraknie odpowiedniego pliku lub nie uda się połączyć z serwerem. Program musi być koniecznie gotowy na taką ewentualność.
    Przykłady: IOException, SQLException
  • RuntimeException – co prawda dziedziczy po klasie Exception, jednak obiekty tej klasy są traktowane w szczególny sposób. Nie jest konieczna ich obsługa, lecz czasami może to się okazać dobrym pomysłem. Zwłaszcza, gdy piszemy jakąś bibliotekę lub API i nie jesteśmy pewni czy będą one używane w bezpieczny sposób przez innych programistów. Najczęściej dotyczą problemów w samym kodzie programu, spowodowanych przez programistę – np. referencja nieoczekiwanie będzie nullem, iteracja po tablicy przekroczy jej rozmiar, funkcja podzieli coś przez zero.
    Przykłady: NullPointerException, IndexOutOfBoundsException

Checked vs Unchecked


  • Exception -> checked
  • Error, RuntimeException -> unchecked

Checked oznacza tyle, że wyjątki te są sprawdzane na etapie kompilacji kodu. Jeśli ich w żaden sposób nie obsłużymy, to programu nie będziemy mogli wykonać. Jest to mechanizm wspierający programistę, dzięki temu zawsze z pełną świadomością decyduje w jaki sposób program ma przebiec dalej po wystąpieniu takiego błędu – nie powinny one przerywać działania programu.
Naturalnie mechanizm ten nie występuje przy Errorach (program musi i tak zostać przerwany) oraz RuntimeException (zwykle nie ma sensu ich obsługiwać, poza tym nie da się przewidzieć w którym momencie taki wyjątek może wystąpić).

Obsługa wyjątku


Co dzieje się z wyjątkiem, gdy go nie obsłużymy?
Obiekt jest tworzony, JVM przechodzi przez stos wywołań (call stack) i sprawdza kolejno w każdej metodzie czy dana klasa wyjątku jest łapana w bloku catch (exception handler). Jeśli dotrze aż do metody main to uruchomi się default exception handler, który drukuje do konsoli opis wyjątku, stack trace i działanie programu zostaje nagle przerwane.

Dlatego, żeby wyjątek obsłużyć, musimy posłużyć się mechanizmem try-catch-finally (więcej w atykule: Java HR: final, finally i finalize).
Przy try możemy dopisać dowolną liczbę bloków catch – od najbardziej szczegółowego do najmniej (dlatego, że gdy wyjątek zostanie złapany w jednym z bloków, program nie dotrze już do kolejnych).

Jeśli nie chcemy w danej metodzie wyjątku bezpośrednio obsługiwać (a jest on checked), trzeba do deklaracji metody dopisać keyword throws i klasę wyjątku występującego w jej wnętrzu.

Informatyk, programista. Obecnie Java Developer (Web Fullstack), właściciel studia Berrygames oraz prezes koła TK Games na Politechnice Wrocławskiej.

Wszystkie artykuły autora>>

Dodaj komentarz