Weź dwa przykłady kodu:
if(optional.isPresent()) {
//do your thing
}
if(variable != null) {
//do your thing
}
O ile mogę stwierdzić, najbardziej oczywistą różnicą jest to, że Opcjonalne wymaga utworzenia dodatkowego obiektu.
Jednak wiele osób zaczęło szybko przyjmować Opcjonalne. Jaka jest zaleta korzystania z opcji zamiast kontroli zerowej?
if
stwierdzenia są baaardzo ostatniej dekadzie, a wszyscy są za pomocą abstrakcji monada lambdy i teraz.if(x.isPresent) fails_on_null(x.get)
że wychodzisz z systemu typów i musisz zachować gwarancję, że kod nie złamie się „w twojej głowie” na (co prawda krótkiej) odległości między warunkiem a wywołaniem funkcji. Woptional.ifPresent(fails_on_null)
systemie typu ta gwarancja jest dla Ciebie i nie musisz się martwić.Optional.ifPresent
(i różnych innych konstrukcji Java) jest to, że można skutecznie modyfikować tylko zmienne końcowe i nie można zgłaszać sprawdzonych wyjątków. Jest to wystarczający powód, aby częstoifPresent
niestety unikać .Odpowiedzi:
Optional
wykorzystuje system typów do wykonywania pracy, którą w innym przypadku musiałbyś wykonać w swojej głowie: pamiętając, czy dane odniesienie może być, czy nienull
. To jest dobre. Zawsze sprytnie jest pozwolić kompilatorowi radzić sobie z nudnymi lekarstwami i zarezerwować ludzkie myśli na twórcze, interesujące prace.Bez tego
Optional
każde odniesienie w twoim kodzie jest jak niewybuchowana bomba. Dostęp do niego może zrobić coś pożytecznego, lub może zakończyć działanie twojego programu z wyjątkiem.Z Opcjonalnym i bez
null
, każdy dostęp do normalnego odwołania powiodło się, a każde odniesienie do Opcjonalnego powiodło się, chyba że jest ono rozbrojone i nie sprawdziłeś tego. To ogromna wygrana w utrzymywalności.Niestety większość obecnie oferowanych języków
Optional
nie została zniesionanull
, więc możesz czerpać korzyści z tej koncepcji, wprowadzając ścisłą zasadę „absolutnie nienull
, nigdy”. DlategoOptional
np. Java nie jest tak atrakcyjna, jak powinna być.źródło
Optional
tylko dla przypomnienia, że wartość może być zerowaWprowadza
Optional
silniejsze pisanie w operacjach, które mogą się nie powieść, jak opisano w innych odpowiedziach, ale jest to dalekie od najciekawszych lub najcenniejszych rzeczy, jakieOptionals
przynoszą na stół. Znacznie bardziej użyteczna jest możliwość opóźniania lub unikania sprawdzania awarii oraz łatwego komponowania wielu operacji, które mogą się nie powieść.Zastanów się, czy masz
optional
zmienną z przykładowego kodu, musisz wykonać dwa dodatkowe kroki, z których każdy może potencjalnie zawieść. Jeśli jakikolwiek krok po drodze zakończy się niepowodzeniem, zamiast tego chcesz zwrócić wartość domyślną. UżywającOptionals
poprawnie, otrzymujesz coś takiego:Z
null
tym musiałbym sprawdzić trzy razynull
przed kontynuowaniem, co dodaje wiele trudności i problemów związanych z konserwacją kodu.Optionals
mieć tę kontrolę wbudowaną w funkcjeflatMap
iorElse
.Uwaga: nie zadzwoniłem
isPresent
ani razu, co należy traktować jako zapach kodu podczas używaniaOptionals
. To niekoniecznie oznacza, że nigdy nie powinieneś używaćisPresent
, po prostu powinieneś dokładnie przeanalizować każdy kod, który ma, aby sprawdzić, czy jest lepszy sposób. W przeciwnym razie masz rację, zyskujesz tylko marginalną korzyść bezpieczeństwa w porównaniu do używanianull
.Zauważ też, że nie martwię się tak bardzo o zawarcie tego wszystkiego w jednej funkcji, aby chronić inne części mojego kodu przed zerowymi wskaźnikami przed wynikami pośrednimi. Jeśli
.orElse(defaultValue)
na przykład sensowniej jest mieć moją w innej funkcji, mam o wiele mniej skrupułów, aby ją tam umieścić i o wiele łatwiej jest skomponować operacje między różnymi funkcjami w razie potrzeby.źródło
Podkreśla możliwość zerowania jako prawidłowej odpowiedzi, której ludzie często zakładają (słusznie lub niesłusznie), że nie zostanie zwrócona. Podświetlenie kilku razy, gdy wartość null jest ważna, pozwala pominąć zaśmiecanie kodu ogromną liczbą bezcelowych kontroli null.
Idealnym ustawieniem zmiennej na wartość NULL byłby błąd czasu kompilacji w dowolnym miejscu oprócz opcji opcjonalnej; eliminowanie wyjątków zerowego wskaźnika środowiska wykonawczego. Oczywiście zgodność wsteczna wyklucza to, niestety
źródło
Dam ci przykład:
Jest całkiem jasne, do czego służy ta metoda. Ale co się stanie, jeśli repozytorium nie zawiera użytkownika o podanym identyfikatorze? Może generować wyjątek, a może zwraca wartość null?
Drugi przykład:
Co się stanie tutaj, jeśli nie będzie użytkownika o podanym identyfikatorze? Tak, masz instancję Optional.absent () i możesz to sprawdzić za pomocą Optional.isPresent (). Podpis metody z Opcjonalnie jest bardziej wyraźny na temat umowy. Od razu wiadomo, jak ma się zachowywać ta metoda.
Ma również zaletę podczas odczytywania kodu klienta:
Wytrenowałem oko, by widzieć .get () jako natychmiastowy zapach kodu. Oznacza to, że klient celowo ignoruje umowę wywoływanej metody. O wiele łatwiej to zobaczyć niż bez Opcjonalnego, ponieważ w takim przypadku nie od razu wiesz, jaki jest kontrakt wywoływanej metody (niezależnie od tego, czy zezwala on na wartość zerową, czy nie), więc musisz to najpierw sprawdzić.
Opcjonalny jest używany z konwencją, że metody z typem zwracanym Opcjonalne nigdy nie zwracają wartości null, a zwykle również z (mniej mocną) konwencją, że metoda bez opcjonalnego typu zwracania nigdy nie zwraca wartości null (ale lepiej jest dodać adnotację @Nonnull, @NotNull lub podobnym) .
źródło
Optional<T>
Pozwala mieć „niepowodzenie” lub „nie wynik” jako ważnej wartości odpowiedź / zwrot z metod (myślę, EG, z odnośnika bazy danych). UżycieOptional
zamiast zamiastnull
do wskazania niepowodzenia / braku wyniku ma pewne zalety:null
może zostać zwrócony.null
ta, przynajmniej moim zdaniem, nie powinna być używana do wskazywania czegokolwiek, ponieważ semantyka może nie być całkowicie jasna. Powinien być użyty do poinformowania śmieciarza, że poprzednio wskazany obiekt może zostać zebrany.Optional
Klasa udostępnia wiele metod ładne warunkowo pracę z wartościami (npifPresent()
) lub zdefiniować domyślne wartości w przejrzysty sposób (orElse()
).Niestety nie eliminuje to całkowicie potrzeby
null
sprawdzania w kodzie, ponieważOptional
sam obiekt nadal może byćnull
.źródło
Oprócz innych odpowiedzi, inną główną zaletą Opcjonalnych, jeśli chodzi o pisanie czystego kodu, jest to, że możesz użyć wyrażenia Lambda w przypadku obecności wartości, jak pokazano poniżej:
źródło
Rozważ następującą metodę:
Teraz spójrzmy na kod wywołujący:
Powoduje to potencjalnie trudną do śledzenia awarię w innym miejscu, ponieważ
dance
nie spodziewał się wartości zerowej.Powoduje to błąd kompilacji, ponieważ taniec oczekiwał
Person
nieOptional<Person>
Jeśli nie mam osoby, powoduje to wyjątek na tej linii, w miejscu, w którym nielegalnie próbowałem przekształcić
Optional<Person>
osobę w Osobę. Kluczem jest to, że w przeciwieństwie do przekazywania wartości null, oprócz śladów tutaj, a nie innych lokalizacji w programie.Podsumowując: niewłaściwe użycie opcji opcjonalnych powoduje łatwiejsze wyśledzenie problemów, niewłaściwe użycie wartości null powoduje trudne do wyśledzenia problemów.
źródło
Optional.get()
kodu, który jest źle napisany - prawie nigdy nie powinieneś wywoływać Optional.get bez uprzedniego sprawdzeniaOptional.isPresent()
(jak wskazano w OP) lub możesz napisaćoptionalPersion.ifPresent(myObj::dance)
.W Objective-C wszystkie odwołania do obiektów są opcjonalne. Z tego powodu kod taki jak napisany przez ciebie jest głupi.
Kod podobny do powyższego jest niespotykany w Objective-C. Zamiast tego programista po prostu:
Jeśli
variable
zawiera wartość,doThing
zostanie na niej wywołana. Jeśli nie, nie zaszkodzi. Program potraktuje to jako brak operacji i będzie kontynuował działanie.To prawdziwa zaleta opcji. Nie musisz zaśmiecać swojego kodu
if (obj != nil)
.źródło
Oczywistym problemem jest to, że jeśli „opcja” naprawdę jest brakujące (czyli jest zerowy), a następnie kod ma zamiar wysadzić z NullReferenceException (lub podobny) próbuje wywołać dowolną metodę na odniesienie obiekt zerowy!
Możesz napisać statyczną metodę klasy Helper, która określa zerowość dowolnego typu obiektu, mniej więcej tak:
lub, być może, bardziej pożytecznie:
Ale czy którekolwiek z nich są naprawdę bardziej czytelne / zrozumiałe / łatwe do utrzymania niż oryginał?
źródło