JavaRush /Java Blog /Random-TL /Coffee break #161. Paano pangasiwaan ang Null sa Java gam...

Coffee break #161. Paano pangasiwaan ang Null sa Java gamit ang Opsyonal

Nai-publish sa grupo
Source: Medium Tutulungan ka ng artikulong ito na mas maunawaan ang layunin ng Opsyonal kapag nagtatrabaho sa Java code. Coffee break #161.  Paano pangasiwaan ang Null sa Java gamit ang Opsyonal - 1Noong una akong nagsimulang magtrabaho sa Java code, madalas akong pinapayuhan na gumamit ng Opsyonal. Ngunit noong panahong iyon ay wala akong gaanong pagkaunawa kung bakit ang paggamit ng Opsyonal ay mas mahusay kaysa sa pagpapatupad ng paghawak para sa mga null na halaga. Sa artikulong ito, gusto kong ibahagi sa iyo kung bakit sa palagay ko dapat nating lahat na gumamit ng Opsyonal nang higit pa, at kung paano maiwasan ang labis na pag-opsyonal sa iyong code, na nakakasama sa kalidad ng code.

Ano ang Opsyonal?

Ang Opsyonal na parameter ay ginagamit upang magdala ng mga bagay at paganahin ang mga null reference na pangasiwaan ng iba't ibang mga API. Tingnan natin ang snippet ng code:
Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
Mayroon kaming instance ng Coffee kung saan nakakakuha kami ng ilang asukal mula sa isang instance ng Sugar object . Kung ipagpalagay namin na ang halaga ng dami ay hindi kailanman naitakda sa Coffee constructor , ang coffee.getSugar().getQuantity() ay magbabalik ng NullPointerException . Siyempre, maaari naming palaging gumamit ng magagandang lumang null check upang ayusin ang problema.
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
  quantity = coffee.getSugar().getQuantity();
}
Ngayon ay tila maayos na ang lahat. Ngunit kapag nagsusulat ng Java code, mas mabuting iwasan natin ang pagpapatupad ng mga null check . Tingnan natin kung paano ito magagawa gamit ang Opsyonal.

Paano gumawa ng Opsyonal

May tatlong paraan upang lumikha ng mga Opsyonal na bagay:
  • of(T value) — instantiation ng isang Optional non-null object. Magkaroon ng kamalayan na ang paggamit ng() upang sumangguni sa isang null object ay magtapon ng NullPointerException .

  • ofNullable(T value) - lumilikha ng Opsyonal na halaga para sa isang bagay na maaaring null.

  • empty() - Lumilikha ng Opsyonal na instance na kumakatawan sa isang reference sa null .

// пример использования 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();
Kaya mayroon kang Opsyonal na bagay. Ngayon tingnan natin ang dalawang pangunahing pamamaraan para sa Opsyonal:
  • isPresent() - Sinasabi sa iyo ng paraang ito kung ang Opsyonal na bagay ay naglalaman ng isang hindi null na halaga.

  • get() - Kinukuha ang halaga para sa Opsyonal na may kasalukuyang halaga. Magkaroon ng kamalayan na ang pagtawag sa get() sa isang walang laman na Opsyonal ay magreresulta sa isang NullPointerException .

Pakitandaan na kung gagamit ka lang ng get() at isPresent() kapag nagtatrabaho sa Opsyonal, nawawala ka! Upang maunawaan ito, muli nating isulat ang halimbawa sa itaas gamit ang Opsyonal.

Pagpapabuti ng Null Checking gamit ang Opsyonal

Kaya paano natin mapapabuti ang code sa itaas? Sa Opsyonal, mauunawaan natin ang presensya ng isang bagay gamit ang isPresent() at makuha ito gamit ang get() . Magsimula tayo sa pamamagitan ng pag-package ng resulta ng coffee.getSugar() na may Opsyonal at gamit ang isPresent() na paraan . Makakatulong ito sa amin na matukoy kung ang getSugar() ay nagbabalik ng null.
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();
}
Sa pagtingin sa halimbawang ito, ang pag-package ng resulta ng coffee.getSugar() sa Opsyonal ay tila hindi nagdaragdag ng anumang halaga, ngunit sa halip ay nagdaragdag ng abala. Mapapabuti natin ang resulta sa pamamagitan ng paggamit ng itinuturing kong paborito kong mga function mula sa Opsyonal na klase:
  • map(Function<? super T,? extends U> mapper) - I-map ang value na nakapaloob sa Opsyonal sa ibinigay na function. Kung walang laman ang Opsyonal na parameter, ibabalik ng map() ang Optional.empty() .

  • orElse(T other) ay isang "espesyal" na bersyon ng get() method . Makukuha nito ang value na nasa Opsyonal. Gayunpaman, sa kaso ng isang walang laman na Opsyonal, ibabalik nito ang halagang ipinasa sa orElse() na paraan .

Ibabalik ng pamamaraan ang halaga na nasa Opsyonal na pagkakataon. Ngunit kung walang laman ang Opsyonal na parameter, ibig sabihin ay wala itong value, ibabalik ng orElse() ang value na ipinasa sa method signature nito, na kilala bilang default na value.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
    .map(it -> it.getQuantity())
    .orElse(0);
Ito ay talagang cool - hindi bababa sa tingin ko. Ngayon, kung sa kaso ng walang laman na halaga hindi namin nais na ibalik ang default na halaga, pagkatapos ay kailangan naming magtapon ng ilang uri ng pagbubukod. orElseThrow(Supplier<? extends X> exceptionSupplier) ay nagbabalik ng value na nakapaloob sa Opsyonal na mga parameter, o nagtatapon ng exception kung ang Opsyonal ay walang laman.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
  .map(it -> it.getQuantity())
  .orElseThrow(IllegalArgumentException::new);
Tulad ng nakikita mo, ang Opsyonal ay nagbibigay ng ilang mga pakinabang:
  • abstracts null checks
  • nagbibigay ng API para sa paghawak ng mga null na bagay
  • nagbibigay-daan sa deklaratibong diskarte na ipahayag kung ano ang nakakamit

Paano maging epektibo sa Opsyonal

Sa aking trabaho, ginagamit ko ang Opsyonal bilang isang uri ng pagbabalik kapag ang isang pamamaraan ay maaaring magbalik ng "walang resulta" na estado. Karaniwang ginagamit ko ito kapag tinutukoy ang mga uri ng pagbabalik para sa mga pamamaraan.
Optional<Coffee> findByName(String name) {
   ...
}
Minsan hindi ito kailangan. Halimbawa, kung mayroon akong paraan na nagbabalik ng int , tulad ng getQuantity() sa klase ng Sugar , maaaring magbalik ng 0 ang pamamaraan kung null ang resulta upang kumatawan sa "walang dami". Ngayon, alam natin ito, maaari nating isipin na ang parameter ng Sugar sa klase ng Kape ay maaaring katawanin bilang Opsyonal. Sa unang tingin, ito ay tila isang magandang ideya dahil, sa teorya, ang asukal ay hindi kailangang naroroon sa kape. Gayunpaman, dito ko gustong tugunan kung kailan hindi gagamitin ang Opsyonal. Dapat nating iwasan ang paggamit ng Opsyonal sa mga sumusunod na sitwasyon:
  • Bilang mga uri ng parameter para sa mga POJO , gaya ng mga DTO . Ang mga opsyonal ay hindi serializable, kaya ang paggamit ng mga ito sa isang POJO ay ginagawang hindi serialize ang object.

  • Bilang argumento ng pamamaraan. Kung ang isang argumentong pamamaraan ay maaaring null , kung gayon mula sa isang purong pananaw ng code, ang pagpasa ng null ay mas mainam pa rin kaysa sa pagpasa sa Opsyonal. Bukod pa rito, maaari kang lumikha ng mga overloaded na pamamaraan upang abstract na pangasiwaan ang kawalan ng isang null method argument.

  • Upang kumatawan sa isang bagay na Koleksyon na nawawala. Maaaring walang laman ang mga koleksyon, kaya ang isang walang laman na Koleksyon , tulad ng isang walang laman na Set o Listahan , ay dapat gamitin upang kumatawan sa isang Koleksyon na walang mga halaga.

Konklusyon

Opsyonal ay naging isang malakas na karagdagan sa Java library. Nagbibigay ito ng paraan upang mahawakan ang mga bagay na maaaring wala. Samakatuwid, dapat itong isaalang-alang kapag bumubuo ng mga pamamaraan nang hindi nahuhulog sa bitag ng pang-aabuso. Oo, maaari kang magsulat ng mahusay na code na nagpapatupad ng mga null check at null handling, ngunit mas gusto ng komunidad ng Java na gumamit ng Opsyonal. Ito ay epektibong nakikipag-usap kung paano pangasiwaan ang mga nawawalang halaga, mas madaling basahin kaysa sa magulo na Null checks, at nagreresulta sa mas kaunting mga bug sa iyong code sa katagalan.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION