Podczas korzystania z Optional
klasy Java 8 istnieją dwa sposoby zawijania wartości w opcjonalne.
String foobar = <value or null>;
Optional.of(foobar); // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException
Rozumiem, że Optional.ofNullable
to jedyny bezpieczny sposób korzystania Optional
, ale dlaczego w ogóle Optional.of
istnieje? Dlaczego po prostu nie korzystać Optional.ofNullable
i być zawsze bezpiecznym?
java.util.Optional
- Jest dostępny, jeśli używasz JDK 8 lub nowszej wersjiofNullable()
nazwaliof()
iof()
nazwaliofNotNull()
Odpowiedzi:
Twoje pytanie opiera się na założeniu, że kod, który może wyrzucić,
NullPointerException
jest gorszy niż kod, który nie może. To założenie jest błędne. Jeśli spodziewasz się, żefoobar
nigdy nie ma wartości zerowej z powodu logiki programu, znacznie lepiej jest go użyć,Optional.of(foobar)
ponieważ zobaczysz komunikat,NullPointerException
który wskaże, że twój program ma błąd. Jeśli użyjesz,Optional.ofNullable(foobar)
afoobar
dzieje się tak znull
powodu błędu, Twój program po cichu będzie nadal działał niepoprawnie, co może być większą katastrofą. W ten sposób błąd może wystąpić znacznie później i znacznie trudniej zrozumieć, w którym momencie się popełnił.źródło
Optional.of(foobar)
”. Wydaje się to nieco dziwne - skoro wiemy, że wartośćnull
w żadnym wypadku nie będzie , to dlaczego nie użyć samej wartości, zamiast owijać ją wewnątrz znakuOptional
?Optional
metody zgodnie z wymaganiami implementowanego interfejsu (prawdopodobnie inni implementatorzy mogą zwrócić pustą opcjonalną). Lub chcesz utworzyć kolekcję / strumień opcji, z których niektóre są gwarantowane jako niezerowe, a niektóre nie. Lub masz logikę warunkową, która tworzy opcjonalną w kilku gałęziach, aw jednej gałęzi masz pewność, że nie jest ona zerowa.null
w tym przypadku oznacza „Oczekuję obecności foobar, ale z powodu błędu jest zerowy”.Optional.isPresent() == false
oznacza, że foobar nie jest obecny, tj. jest to oczekiwane, uzasadnione zachowanie.return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));
list
null
Ponadto, jeśli wiesz, że Twój kod nie powinien działać, jeśli obiekt ma wartość NULL, możesz zgłosić wyjątek za pomocą
Optional.orElseThrow
źródło
String name = Objects.requireNonNull(nullName);
NullPointerException
wtedy, gdy problem wyraźnie stanowi odniesienie, którenull
nie powinno, byłoby krokiem w złym kierunku.new NullNameException("meaningful msg")
To zależy od scenariuszy.
Załóżmy, że masz pewną funkcjonalność biznesową i musisz dalej przetwarzać coś o tej wartości, ale posiadanie
null
wartości w czasie przetwarzania wpłynęłoby na to.Następnie w takim przypadku możesz użyć
Optional<?>
.źródło
Opcjonalnie i tak należy stosować głównie w przypadku wyników Usług. W usłudze wiesz, co masz pod ręką i zwracasz Optional.of (someValue), jeśli masz wynik, i zwracasz Optional.empty (), jeśli nie masz. W takim przypadku pewna wartość nigdy nie powinna być pusta i nadal zwracana jest opcja.
źródło