Wyjątki w Java: NullPointerException

NullPointerExcepion to chyba najczęściej spotykany wyjątek w Java, co więcej wynika on zazwyczaj z błędu programisty. Oznacza on przeważnie wywołanie metody na obiekcie, który ma wartość null.

Często błąd ten występuje, kiedy przez pomyłkę jeden z parametrów wykonywanej metody ma wartość null. OK, ale co to właściwie znaczy? Przyjrzyjmy się prostemu przykładowi:

Żeby nadmiernie nie komplikować kodu, opakowujemy standardową metodę concat z klasy String w naszą prywatną metodę concatenate, która przyjmuje dwa parametry typu String.

Jeżeli uruchomimy, aplikację dostaniemy następujący rezultat:

Oto jest i on, słynny NullPointerException! Zacznijmy od ostatniej linii tj.: at pl.naukajava.NullPointerExceptionExample.main(NullPointerExceptionExample.java:7), która to wskazuje, że błąd występuje w 7 linii naszej aplikacji tj.:

Kolejna linia w stack trace wskazuje nam na naszą metodę concatenate(String, String). Natomiast tutaj: at java.lang.String.concat(String.java:2027) mamy odwołanie do standardowej metody concat z klasy String.

Co z tego wszystkiego wynika? Otóż metoda concat nie działa jeżeli przekażemy jej wartość null jako parametr. Jak to poprawić? Jest wiele możliwych rozwiązań:

  1. zamienić wartość null na pusty String
  2. zamienić wartość null na String „null”
  3. w metodzie concatenate dodać warunek if (b == null) i wtedy podmienić tą wartość na pusty String lub String „null”
  4. w metodzie concatenate dodać warunek if (b == null) i rzucić wyjątek IllegalArgumentException

Oczywiście dobre rozwiązanie będzie się różnić od tego, jaki efekt chcemy osiągnąć. Ja, osobiście składniam się do 3 propozycji i zamiany wartości null na String „null”.

Nowa wersja metody concatenate będzie wyglądała następująco:

Jeżeli teraz uruchomimy ponownie tą aplikację, to znowu otrzymamy NullPointerException, tym razem w linii 8… no i tym razem sami jesteśmy sobie winni. Gdyż nie sprawdzamy wartości zmiennej a tylko bezpośrednio wywołujemy na niej metodę concat, co w rezultacie daje nam NPE (akronim od NullPointerException).

Ponownie wypadało by się zabezpieczyć przed tym błędem. Najlepiej w sposób konsystentny z tym w jaki poprawiliśmy pierwszy błąd tj. zamienić null na String „null”. Mamy już kod który wykonuje dokładnie taką operację dla zmiennej b, więc albo możemy go skopiować (źle, źle, źle, źle..,), albo wyciągnąć go do nowej metody np. nullToString.

Musimy teraz zmienić metodę concatenate, żeby korzystała z nowo utworzonej metody nullToString:

Teraz nasza mała aplikacja demonstracyjna będzie działa tak bez problemów.

W ten oto sposób pozbywamy się z aplikacji błędów typu NullPointerException.

Spodobał się Tobie ten wpis? Podziel się nim ze znajomymi

3 Comments Wyjątki w Java: NullPointerException

  1. Pingback: JVM Bloggers - best posts in December 2016 - Tomasz Dziurko

  2. Krzysztof Chruściel

    Cześć, jeśli chodzi o samo pokazanie czym jest NullPointerException to jest to przedstawione w bardzo dobry sposób. Natomiast ja zastosował bym Optional’e dla radzenia sobie z obiektami które mogą być Null’ami. W momencie którym Optional.IfPresent zwróci false wtedy rzucił bym własny wyjątek który jasno mówi co się stało. Zwracanie stringa null nie jest dobry rozwiązaniem bo dopóki Ty pracujesz na tym kodzie to wiesz że null w Stringu oznacza błąd, natomiast ktoś inny może pomyśleć że taka wartość przyszła od klienta.

    Reply
    1. Dariusz Łuksza

      Tak, użycie Optional jest lepszym rozwiązaniem od stosowania null’i zwłaszcza w bibliotekach oraz publicznym API. Jenak w tym wpisie nie chciałem wprowadzać jeszcze typu Optional, gdyż załuguje on na osobny wpis. Dodatkowo do jego użycia potrzebna jest znajomość typów generycznych (Generics) o których też jescze nie pisałem. Dlatego zdecydowałem się na proste przykłady z użyciem null’i.

      Zapraszam ponowie za jakiś czas 😉

      Reply

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *