Könüllü nədir?
Könüllü parametr obyektləri daşımaq və null istinadların müxtəlif API-lər tərəfindən idarə olunmasını təmin etmək üçün istifadə olunur. Gəlin kod parçasına baxaq:Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
Şəkər obyektinin bir nümunəsindən müəyyən miqdarda şəkər əldə etdiyimiz Qəhvə nümunəmiz var . Qəhvə konstruktorunda kəmiyyət dəyərinin heç vaxt təyin edilmədiyini fərz etsək , coffee.getSugar().getQuantity() NullPointerException qaytaracaq . Əlbəttə ki, problemi həll etmək üçün həmişə köhnə boş yoxlamalardan istifadə edə bilərik.
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
quantity = coffee.getSugar().getQuantity();
}
İndi hər şey yaxşı görünür. Lakin Java kodunu yazarkən null yoxlamalarından qaçmaq daha yaxşıdır . Bunun Könüllü istifadə edərək necə edilə biləcəyinə baxaq.
Könüllü necə yaradılır
Könüllü obyektlər yaratmağın üç yolu var:-
of(T dəyəri) — Könüllü qeyri-null obyektin nümunəsi. Unutmayın ki, of() null obyektə istinad etmək üçün istifadə NullPointerException atacaq .
-
ofNullable(T dəyəri) - null ola bilən obyekt üçün Əlavə dəyər yaradır.
-
empty() - null istinadını təmsil edən Könüllü nümunə yaradır .
// пример использования Optional.of(T Value)
String name = "foo";
Optional<String> stringExample = Optional.of(name)
// пример использования Optional.ofNullable(T Value)
Integer age = null;
Optional<Integer> integerExample= Optional.ofNullable(age)
// пример использования Optional.empty()
Optional<Object> emptyExample = Optional.empty();
Beləliklə, bir Könüllü obyektiniz var. İndi Könüllü üçün iki əsas üsula nəzər salaq:
-
isPresent() - Bu metod sizə Könüllü obyektin qeyri-null dəyərinin olub olmadığını bildirir.
-
get() - Könüllü üçün dəyəri cari dəyərlə əldə edir. Nəzərə alın ki, get() funksiyasının boş istəyə bağlı çağırılması NullPointerException ilə nəticələnəcək .
Könüllü ilə Null Yoxlamanın Təkmilləşdirilməsi
Beləliklə, yuxarıdakı kodu necə təkmilləşdirə bilərik? Könüllü ilə biz isPresent() istifadə edərək obyektin mövcudluğunu başa düşə və get() istifadə edərək onu əldə edə bilərik . Gəlin coffee.getSugar() nəticəsini Opsiyonel ilə qablaşdırmaqla və isPresent() metodundan istifadə etməklə başlayaq . Bu, getSugar() funksiyasının null qaytarıb-qaytarmadığını müəyyən etməyə kömək edəcək .Coffee coffee = new Coffee();
Optional<String> sugar = Optional.ofNullable(coffee.getSugar());
int quantity = 0;
if (sugar.isPresent()) {
Sugar sugar = sugar.get();
int quantity = sugar.getQuantity();
}
Bu nümunəyə baxsaq, coffee.getSugar() nəticəsinin Opsiyonel-ə qablaşdırılması heç bir dəyər əlavə etmir, əksinə, çətinlik yaradır. Könüllü sinifdən sevimli funksiyalarım hesab etdiyim funksiyalardan istifadə etməklə nəticəni yaxşılaşdıra bilərik:
-
map(Function<? super T,? extensions U> mapper) - Əlavədə olan dəyəri təqdim edilmiş funksiyaya uyğunlaşdırır. Əgər Könüllü parametr boşdursa, map() Optional.empty() funksiyasını qaytaracaq .
-
orElse(T other) get() metodunun “xüsusi” versiyasıdır . İsteğe bağlı olan dəyəri əldə edə bilər. Bununla belə, boş İsteğe bağlı halda, bu orElse() metoduna ötürülən dəyəri qaytaracaq .
Coffee coffee = new Coffee();
Integer quantity = Optional.ofNullable(coffee.getSugar())
.map(it -> it.getQuantity())
.orElse(0);
Bu, həqiqətən gözəldir - ən azı mən belə düşünürəm. İndi boş dəyər vəziyyətində standart dəyəri qaytarmaq istəmiriksə, bir növ istisna atmaq lazımdır. orElseThrow(Supplier<? extensions X> exceptionSupplier) Könüllü parametrlərdə olan dəyəri qaytarır və ya Könüllü boşdursa, istisna atır.
Coffee coffee = new Coffee();
Integer quantity = Optional.ofNullable(coffee.getSugar())
.map(it -> it.getQuantity())
.orElseThrow(IllegalArgumentException::new);
Gördüyünüz kimi, Opsiyonel bir sıra üstünlükləri təmin edir:
- null çekləri abstrakt edir
- null obyektləri idarə etmək üçün API təmin edir
- deklorativ yanaşma əldə olunanı ifadə etməyə imkan verir
Könüllü ilə necə effektiv olmaq olar
İşimdə, bir metod “nəticə yoxdur” vəziyyətini qaytara bildikdə, qaytarma növü kimi Könüllü istifadə edirəm. Mən adətən metodlar üçün qaytarma növlərini təyin edərkən istifadə edirəm.Optional<Coffee> findByName(String name) {
...
}
Bəzən bu lazım deyil. Məsələn, Şəkər sinfində getQuantity() kimi int qaytaran metodum varsa , nəticə “kəmiyyət yoxdur” ifadəsi üçün null olarsa, metod 0 qaytara bilər. İndi bunu bilərək, Qəhvə sinfində Şəkər parametrinin Opsiyonel olaraq göstərilə biləcəyini düşünə bilərik . İlk baxışdan bu yaxşı fikir kimi görünür, çünki nəzəri olaraq şəkərin qəhvədə olması lazım deyil. Bununla belə, Könüllü istifadə etməmək üçün müraciət etmək istədiyim yer budur . Aşağıdakı ssenarilərdə Könüllü istifadə etməkdən çəkinməliyik:
-
DTO kimi POJO-lar üçün parametr növləri kimi . Seçimlər seriallaşdırıla bilməz, ona görə də onlardan POJO-da istifadə obyektin serializasiyasını qeyri-aktiv edir.
-
Metod arqumenti kimi. Metod arqumenti null ola bilərsə , təmiz kod baxımından null keçmək hələ də Könüllü olaraq keçməyə üstünlük verilir. Bundan əlavə, null metod arqumentinin olmamasını mücərrəd şəkildə idarə etmək üçün həddindən artıq yüklənmiş metodlar yarada bilərsiniz.
-
Çatışmayan Kolleksiya obyektini təmsil etmək üçün. Kolleksiyalar boş ola bilər, buna görə də dəyərsiz Kolleksiyanı təmsil etmək üçün boş Dəst və ya Siyahı kimi boş Kolleksiyadan istifadə edilməlidir.
GO TO FULL VERSION