2015-02-26 7 views
17

W języku Java 8 można zwrócić wartość Optional zamiast null. Dokumentacja Java 8 mówi, że opcjonalne to "obiekt kontenerowy, który może zawierać wartość inną niż null lub nie, a jeśli wartość jest obecna, to metoda isPresent() zwróci wartość true, a funkcja get() zwróci wartość."Opcjonalne w przeciwieństwie do wartości null. Jaki jest cel Opcjonalnego w Java 8?

Dlaczego w praktyce jest to przydatne? Czy istnieje również przypadek, w którym preferowane byłoby używanie null? A co z wydajnością?

Odpowiedz

20

Dlaczego w praktyce jest to przydatne?

Na przykład załóżmy, że masz ten strumień liczb całkowitych i robisz filtrowanie:

int x = IntStream.of(1, -3, 5) 
       .filter(x -> x % 2 == 0) 
       .findFirst(); //hypothetical assuming that there's no Optional in the API 

nie wiesz z góry, że operacja filtr usunie wszystkie wartości w Strumieniu .

Załóżmy, że w interfejsie API nie będzie opcji Opcjonalne. W takim przypadku, co powinieneś zwrócić: findFirst?

Jedynym możliwym sposobem byłoby wyrzucenie wyjątku, takiego jak NoSuchElementException, co jest IMO dość irytujące, ponieważ nie uważam, że powinno to zatrzymać wykonywanie programu (lub musiałbyś złapać wyjątek, nie bardzo wygodne) i kryteria filtrowania mogą być bardziej złożone.

Przy użyciu numeru Optional, od dzwoniącego zależy sprawdzenie, czy Optional jest pusty, czy nie (np. Jeśli obliczenie zakończyło się wartością lub nie).

z typem odniesienia, można również powrócić null (ale null mogłaby być możliwa wartość w przypadku filtrować tylko null wartości, więc wracamy do sprawy wyjątków).

Jeśli chodzi o zastosowania inne niż strumieniowe, to oprócz zapobiegania NPE, myślę, że pomaga to również zaprojektować bardziej przejrzyste API, które mówi, że wartość może być obecna. Na przykład rozważyć tę klasę:

class Car { 
    RadioCar radioCar; //may be null or not 
    public Optional<RadioCar> getRadioCar() { 
     return Optional.ofNullable(radioCar); 
    } 
} 

Tu są wyraźnie mówiący do rozmówcy, że radio w samochodzie jest opcjonalny, może to być albo nie istnieje.

+1

Opcjonalne nie może zawierać wartości null ... – ZhongYu

4

Pozwala to uniknąć konieczności wykonywania uciążliwych sprawdzeń zerowych, ponieważ zawsze wiesz, że zwracany jest obiekt Optional. Jest również mocno wykorzystywany przez strumień API.

+0

Jak unikniesz kontroli NULL? Nadal musisz zrobić to samo, tylko z .isPresent(), a następnie musisz wykonać wywołanie metody, aby uzyskać obiekt. A jeśli wywołasz .of(), może on nadal wyrzucać NULL POINTER EXCEPTION, więc teraz potrzebujesz bloku try/catch lub KOLEJNEGO testu IF dla NULL. Opcjonalne wymaga więcej kodu nie mniej. – BrianC

+1

Ponieważ 'Opcjonalny' nie ma wartości NULL. Może być pusty, ale nie jest pusty. Nigdzie nie powiedziałem, że 'Opcjonalnie' wymaga mniej kodu. Używanie 'isPresent()' jest po prostu złym użyciem zwykle (wskazując, że używasz "Opcjonalnie" źle) i nie ma absolutnie potrzeby testowania wartości zerowej lub przechwytywania 'NPE'. Twój komentarz brzmi, jakbyś nie przeczytał nawet javadoc dla 'Opcjonalnie'. Zalecam sprawdzenie przynajmniej metod 'orElse()' i 'map()'. – Kayaman

+0

Niestety, nie oznacza to, że powiedziałeś, że jest to mniej kodu, to jest argument generalnie podany przy użyciu Opcjonalnego. Zapisuje kod, nie wykonując kontroli NULL. Nadal musisz wiedzieć, czy rzeczywiście masz obiekt, czy nie. Bez względu na to, z której metody korzystasz (isPresent(), lubElse(), itp.) Nadal musisz sprawdzić, czy naprawdę masz obiekt, czy nie, a używanie Opcjonalnie do tego sprawia, że ​​jest o wiele trudniejsze i bardziej skomplikowane. – BrianC

1

Opcjonalnie pomaga obsługiwać zmienne jako dostępne lub niedostępne i unikać sprawdzania odwołań zerowych.

+0

Co to znaczy, że zmienna jest dostępna lub niedostępna? –

+1

Odwołanie zerowe jest oczywiście niedostępne, dostępne w inny sposób, użyjesz metody 'Opcjonalnie # isPresent' do bezpiecznego sprawdzenia dla tego – user3728064

+0

Jak unikniesz kontroli NULL? Nadal musisz to zrobić z .isPresent(), a następnie musisz wykonać wywołanie metody, aby uzyskać obiekt. Więc to jest więcej kodu I jeśli zadzwonisz .of, to nadal możesz rzucić WYJĄTKOWY POINTER POINT, więc teraz potrzebujesz bloku try/catch lub INNEGO testu IF dla NULL. Opcjonalne wymaga więcej kodu nie mniej. – BrianC

13

Po pierwszym zaprojektowaniu Javy powszechną praktyką było używanie specjalnej wartości, zwykle o nazwie null, aby wskazać specjalne okoliczności, takie jak . Nie mogłem znaleźć tego, czego szukałeś. Ta praktyka została przyjęta przez Javę.

Od tego czasu zasugerowano, że praktyka ta powinna być uważana za anty-wzór, szczególnie w przypadku obiektów, ponieważ oznacza to, że trzeba zaśmiecać kod za pomocą zerowych kontroli w celu osiągnięcia niezawodności i stabilności. Jest to również uciążliwe, gdy chcesz umieścić na przykład kolekcję null.

Współczesne podejście polega na użyciu specjalnego obiektu, który może lub nie może mieć wartości. W ten sposób możesz bezpiecznie utworzyć jeden i po prostu go nie wypełniać. Tutaj widzisz Java 8 zachęcającą do stosowania tej najlepszej praktyki, dostarczając obiekt Optional.

+21

Czy można wyjaśnić, dlaczego zerowanie jest zbędne, ale wywołanie funkcji Opcjonalne.isPresent nie jest? – user100464

+1

Chciałbym również wiedzieć ... – ycomp

+9

Jeśli używałeś tylko Opcjonalnego jako bezpośredniego zamiennika dla bezpośrednich zerowych sprawdzeń z 'Opcjonalnie.jestPrzykładem', to byłoby to mało przydatne (nadal daje ci wyraźną deklarację na stronach z telefonami, że ta wartość może być nieobecnym, co jest dobre); Prawdziwa moc pochodzi z tego, że możemy * odroczyć * obsługę błędów (brak wartości) do późniejszego czasu i zastosować metody map/flatMap/filter itd. bez bloków if/else. –