Sprawdzanie Nulla pomijajac wielokrotne ify

0

Są wywoływane metody na obiekcie:

JakisObiekt jakisObiekt = new JakisObiekt();

jakisObiekt.get1().get2().get3().get4().get5();

i teraz jak sprawdzic nulla porzadnie zeby mi od razu pokazalo gdzie on jest nie bawiac sie w ify?

Czyli zeby nie stosowac:

if(jakisObiekt.get1() == null) 
log.error("get1 is null);

else if(jakisObiekt.get1().get2() == null) 
log.error("get2 is null);

itd.

7

Nie da się tak, chyba że stosujesz Optionale, możesz wtedy mieć kaskadę wywołań map/flatMap

1

Dodam, języki Kotlin czy Groovy mają operator Elvis, to czasem ułatwia życie z tradycyjnymi nullami.

Optional jest fajny, bo:

  • jest nie tylko na poziomie działania (wewnątrz kodu), ale ma rolę deklaracyjną.
  • ten z Javy 8 (nieco ulepszony chyba w 11) nie obiecuje zbawienia świata, lecz ma ograniczone ambicje.

generalnie to dział Javy jest pełen dyskusji nad nullami, poszukaj trochę.

1
Optional.of(jakisObiekt)
.map(x->x.get1())
.map(x->x.get2())
.map(x->x.get3())
.map(x->x.get4())
.map(x->x.get5())
.orElse...
5

@zgrzyt:

zgrzyt napisał(a):

Są wywoływane metody na obiekcie:

JakisObiekt jakisObiekt = new JakisObiekt();

jakisObiekt.get1().get2().get3().get4().get5();

i teraz jak sprawdzic nulla porzadnie zeby mi od razu pokazalo gdzie on jest nie bawiac sie w ify?

To zadaj sobie pytanie czemu w kolejnych get1(), get2(), get3() mogą być null? One są tam by design (i coś oznaczają), czy są tam przypadkiem i próbujesz robić jakieś programowanie defensywne?

Niezależe wywołania

Bo jeśli coś oznaczają, np ktoś zaprojektował ("zaprojektował" w cudzysłowie) API w którym null symbolizuje np nieistniejący zasób, albo jakieś nieustawione pole; to ja nie radziłbym po prostu tego zignorować takim ifem albo map()ami, tylko obsłużyć w jakiś sensowny sposób; bo rozumiem że każdy z tych get1(), get2() może mieć inny powód wystąpienia nulla? Bo możliwe że brak get2() ma inną przyczynę niż get4(), co należałoby obsłużyć w różny sposób.

Drzewo

Jeśli natomiast każdy z tych get1(), get2() symbolizuje jakąś zagnieżdżoną strukturę, np drzewo, system plików, etc. to nie wiem czy symbolizowanie nullem brakującego pola to dobry pomysł, ja raczej bym zrobił coś takiego:

try {
  return root.get1().get2().get3().get4().get5();
} 
catch (NieMaWartościException ex) {
    return root; // albo coś innego
}

Wtedy każdy ten getX() robiłby throw new NieMaWartości() zamiast return null.

Programowanie defensywne

Jeśli natomiast to ma być programowanie defensywne, tzn tam nie ma być nulla, i tylko obawiasz się że będzie, wiec robisz ify... to nie rób. Jeśli tam nie ma być nulla, a przypadkiem się zjawi to niech rzuci NPE i tyle, po to jest. I potem szukaj przyczyn w tej metodzie która zwróciła nulla (bo przecież nie powinna), a nie w funkcji która go dostała.

Struktura

Jeśli jednak to jest struktura, a nie obiektówka, np

gameRoom.user.region.name

To wtedy faktycznie mógłbyś próbować chainować optionale, jeśli chcesz. Ale wtedy, jak już zostało zauważone, może to znaczyć żę została złamana hermetyzacja, no chyba że to jest model.

1

@zgrzyt:
W sumie nic nie musisz robić.

JakisObiekt jakisObiekt = new JakisObiekt();

jakisObiekt.get1().get2().get3().get4().get5();

Jeśli wywołasz to na javie 14 lub nowszej to java powie Ci sama gdzie ten null jest.

Cannot invoke "pl.setblack.wisnia.nulle.NullsTest.get4()" because the return value of "pl.setblack.wisnia.nulle.NullsTest.get3()" is null
1

Zacznijmy od prawa Demeter (hermetyzacji), taki ciąg wywołań najprawdopodobniej wskazuje na kiepski design. Dopiero potem pudrujmy kupę jakimiś flatmapami :)

3

@Charles_Ray może tak może nie ;) Jesli to faktycznie get to pewnie tak, ale to moze być jakiś ciąg wywołań jakichś faktycznych operacji czy transformacji (tylko słabo napisany i zamiast zwracać Optionale zwraca nulle).

0
Charles_Ray napisał(a):

Zacznijmy od prawa Demeter (hermetyzacji), taki ciąg wywołań najprawdopodobniej wskazuje na kiepski design. Dopiero potem pudrujmy kupę jakimiś flatmapami :)

Nie koniecznie. Jeśli to są ciągi pól to faktycznie, ale mogą to być po prostu zinlineowane zmienne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1