Jak używać i jak nie używać klasy Optional w Javie?
Zaktualizowaliśmy ten tekst dla Ciebie!
Data aktualizacji: 30.12.2024
Autor aktualizacji: Kamil Drabik
Jeśli masz dość sprawdzania obiektów pod kątem wartości null i chcesz uczynić swój kod bardziej czytelnym, powinieneś rozważyć użycie klasy Optional. Jest to kontener używany do reprezentowania wartości null jako brakującej wartości.
Wprowadzenie
Jeśli masz dość sprawdzania obiektów pod kątem wartości null i chcesz uczynić swój kod bardziej czytelnym, powinieneś rozważyć użycie klasy Optional. Jest to kontener używany do reprezentowania wartości null jako brakującej wartości.
Stare sprawdzanie null
if(house != null) {
doSomething(house);
}
Nowe sprawdzanie null za pomocą Optional
Optional<house> maybeHouse = Optional.ofNullable(house);
if(maybeHouse.isPresent()) {
doSomething(maybeHouse.get());
}
Jak poprawnie używać Optional?
Jest to prawie takie samo jak „stare” sprawdzanie null i jest to antywzorzec.
- ofNullable(T value) Zwraca Optional opisujący podaną wartość, jeśli nie jest ona null, w przeciwnym razie zwraca pusty Optional.
- isPresent() Zwraca true, jeśli wartość jest obecna, w przeciwnym razie false.
- get() Jeśli wartość jest obecna w tym Optional, zwraca tę wartość, w przeciwnym razie rzuca NoSuchElementException.
A właściwy sposób:
Optional<house> maybeHouse = Optional.ofNullable(house);
maybeHouse.ifPresent(this::doSomething);
Możesz użyć referencji do metody lub lambdy, aby uczynić kod bardziej czytelnym.
- isPresent(Consumer; consumer) Jeśli wartość jest obecna, wywołuje określonego konsumenta z tą wartością, w przeciwnym razie nic nie robi.
Wartość domyślna
Klasa Optional udostępnia interfejsy API do zwracania wartości obiektu lub wartości domyślnej, jeśli obiekt jest pusty.
Table table1 = null;
Table table2 = new Table("green");
Table result = Optional.ofNullable(table1).orElse(table2);
Tak więc, jeśli pierwszy obiekt jest null, zwrócony zostanie drugi obiekt. Jeśli pierwszy obiekt nie jest null, wartość domyślna zostanie zignorowana.
- orElse(T other) Zwraca wartość, jeśli jest obecna, w przeciwnym razie zwraca other.
Możesz również rzucić wyjątek, jeśli obiekt jest null.
Table table1 = null;
Table result = Optional.ofNullable(table1).orElseThrow(IllegalStateException::new);
- orElseThrow(Supplier exceptionSupplier) Zwraca zawartą wartość, jeśli jest obecna, w przeciwnym razie rzuca wyjątek utworzony przez dostarczonego dostawcę.
Filtr
Zazwyczaj musisz sprawdzić właściwość swojego obiektu, który może być null, a następnie użyć metody filter.
Na przykład, chcesz wiedzieć, czy table1 jest czarna.
Table table1 = new Table("green");
Boolean isBlueTable = Optional.ofNullable(table1)
.filter(e -> e.getColour() == "black")
.isPresent();
- filter(Predicate predicate) Jeśli wartość jest obecna i wartość spełnia dany predykat, zwraca Optional opisujący tę wartość, w przeciwnym razie zwraca pusty Optional.
FlatMap
Przyjrzyjmy się teraz problemowi kaskadowania w poprzedniej wersji Javy.
String tableColour = house.getRoom().getTable().getColour();
Aby pobrać kolor stołu znajdującego się w pokoju w twoim domu, musisz sprawdzić, czy nie ma żadnych wartości null na drodze, aby zapobiec NullPointerException.
String tableColour;
if(house != null) {
Room room = house.getRoom();
if(room != null) {
Table table = room.getTable();
if(table != null) {
tableColour = table.getColour();
}
}
}
Teraz twój kod jest bezpieczny, ale ze względu na zagnieżdżone sprawdzanie null nie jest czysty i wygląda brzydko. Optional daje alternatywę i czystszy sposób obsługi wielu sprawdzeń null.
Najpierw zaktualizuj swoją klasę, aby korzystać z Optional.
class House {
Optional<Room> room;
public Optional<Room> getRoom() {
return room;
}
}
class Room {
Optional<Table> table;
public Optional<Table> getTable() {
return table;
}
}
class Table {
String colour;
public String getColour() {
return colour;
}
...
Po refaktoryzacji nie musisz używać zagnieżdżonych sprawdzeń null i jest bardziej jasne, że na przykład Room może mieć stół, ale nie jest to konieczne.
Przyjrzyjmy się nowemu sposobowi sprawdzania null za pomocą flatMap i map.
String tableColour = Optional.ofNullable(house)
.flatMap(House::getRoom)
.flatMap(Room::getTable)
.map(Table::getColour)
.orElse("black");
Kod jest czysty i bardziej czytelny.
- map(Function< super T,? extends U> mapper) Jeśli wartość jest obecna, stosuje dostarczoną funkcję mapującą do niej, a jeśli wynik nie jest null, zwraca Optional opisujący wynik.
- flatMap(Function> mapper) Jeśli wartość jest obecna, stosuje dostarczoną funkcję mapującą zwracającą Optional do niej, zwraca ten wynik, w przeciwnym razie zwraca pusty Optional.
Podsumowanie
Optional to jedna z najbardziej użytecznych funkcji wprowadzonych w Javie 8+, która pomaga w miejscach, gdzie musisz zmierzyć się z NullPointerException. Dzięki niej Twój kod będzie bardziej czytelny, bezpieczny i łatwiejszy w utrzymaniu.
Bibliografia:
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
Poznaj mageek of j‑labs i daj się zadziwić, jak może wyglądać praca z j‑People!
Skontaktuj się z nami


