JavaRush /Java Blog /Random-ID /Rehat kopi #161. Cara menangani Null di Java menggunakan ...

Rehat kopi #161. Cara menangani Null di Java menggunakan Opsional

Dipublikasikan di grup Random-ID
Sumber: Medium Artikel ini akan membantu Anda lebih memahami tujuan Opsional saat bekerja dengan kode Java. Rehat kopi #161.  Cara menangani Null di Java menggunakan Opsional - 1Ketika saya pertama kali mulai bekerja dengan kode Java, saya sering disarankan untuk menggunakan Opsional. Namun pada saat itu saya kurang memahami mengapa menggunakan Opsional lebih baik daripada menerapkan penanganan untuk nilai nol. Dalam artikel ini, saya ingin berbagi dengan Anda mengapa menurut saya kita semua harus lebih sering menggunakan Optional, dan bagaimana menghindari over-opsionalisasi kode Anda, yang dapat merusak kualitas kode.

Apa itu Opsional?

Parameter Opsional digunakan untuk membawa objek dan mengaktifkan referensi null untuk ditangani oleh berbagai API. Mari kita lihat cuplikan kodenya:
Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
Kita mempunyai instance Coffee yang mana kita mendapatkan gula dari instance objek Sugar . Jika kita berasumsi bahwa nilai quantity tidak pernah disetel di konstruktor Coffee , maka coffee.getSugar().getQuantity() akan mengembalikan NullPointerException . Tentu saja, kita selalu dapat menggunakan pemeriksaan null lama yang bagus untuk memperbaiki masalah.
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
  quantity = coffee.getSugar().getQuantity();
}
Sekarang semuanya tampak baik-baik saja. Namun saat menulis kode Java, sebaiknya kita menghindari penerapan pemeriksaan null . Mari kita lihat bagaimana hal ini dapat dilakukan menggunakan Opsional.

Cara membuat Opsional

Ada tiga cara untuk membuat objek Opsional:
  • of(T value) — instantiasi objek non-null Opsional. Sadarilah bahwa menggunakan of() untuk merujuk ke objek null akan memunculkan NullPointerException .

  • ofNullable(T value) - menciptakan nilai Opsional untuk objek yang bisa berupa null.

  • kosong() - Membuat instance Opsional yang mewakili referensi ke 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();
Jadi, Anda memiliki objek Opsional. Sekarang mari kita lihat dua metode utama untuk Opsional:
  • isPresent() - Metode ini memberitahu Anda apakah objek Opsional berisi nilai bukan nol.

  • get() - Mengambil nilai Opsional dengan nilai saat ini. Ketahuilah bahwa memanggil get() pada Optional yang kosong akan menghasilkan NullPointerException .

Harap perhatikan bahwa jika Anda hanya menggunakan get() dan isPresent() saat bekerja dengan Opsional, Anda ketinggalan! Untuk memahami hal ini, sekarang mari kita tulis ulang contoh di atas dengan Opsional.

Meningkatkan Pemeriksaan Null dengan Opsional

Jadi bagaimana kita bisa memperbaiki kode di atas? Dengan Optional kita dapat memahami keberadaan suatu objek menggunakan isPresent() dan mengambilnya menggunakan get() . Mari kita mulai dengan mengemas hasil coffee.getSugar() dengan Optional dan menggunakan metode isPresent() . Ini akan membantu kita menentukan apakah getSugar() mengembalikan 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();
}
Melihat contoh ini, mengemas hasil coffee.getSugar() ke dalam Optional sepertinya tidak menambah nilai apa pun, melainkan menambah kerumitan. Kita dapat meningkatkan hasilnya dengan menggunakan apa yang saya anggap sebagai fungsi favorit saya dari kelas Opsional:
  • map(Function<? super T,? extends U> mapper) - Memetakan nilai yang terkandung dalam Opsional ke fungsi yang disediakan. Jika parameter Optional kosong, maka map() akan mengembalikan Optional.empty() .

  • orElse(T other) adalah versi "khusus" dari metode get() . Itu bisa mendapatkan nilai yang terkandung dalam Opsional. Namun, jika Opsional kosong, ini akan mengembalikan nilai yang diteruskan ke metode orElse() .

Metode ini akan mengembalikan nilai yang terdapat dalam instance Opsional. Namun jika parameter Optional kosong, artinya tidak mengandung nilai, maka orElse() akan mengembalikan nilai yang diteruskan ke tanda tangan metodenya, yang dikenal sebagai nilai default.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
    .map(it -> it.getQuantity())
    .orElse(0);
Ini sangat keren - setidaknya menurut saya begitu. Sekarang, jika dalam kasus nilai kosong kita tidak ingin mengembalikan nilai default, maka kita perlu memberikan semacam pengecualian. orElseThrow(Supplier<? extends X> pengecualianSupplier) mengembalikan nilai yang terdapat dalam parameter Opsional, atau memunculkan pengecualian jika Opsional kosong.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
  .map(it -> it.getQuantity())
  .orElseThrow(IllegalArgumentException::new);
Seperti yang Anda lihat, Opsional memberikan beberapa keuntungan:
  • abstrak pemeriksaan nol
  • menyediakan API untuk menangani objek null
  • memungkinkan pendekatan deklaratif untuk mengungkapkan apa yang sedang dicapai

Bagaimana menjadi efektif dengan Opsional

Dalam pekerjaan saya, saya menggunakan Opsional sebagai tipe pengembalian ketika suatu metode dapat mengembalikan keadaan “tidak ada hasil”. Saya biasanya menggunakannya ketika mendefinisikan tipe pengembalian untuk metode.
Optional<Coffee> findByName(String name) {
   ...
}
Terkadang hal ini tidak diperlukan. Misalnya, jika saya memiliki metode yang mengembalikan int , seperti getQuantity() di kelas Sugar , maka metode tersebut mungkin mengembalikan 0 jika hasilnya null untuk mewakili “tidak ada kuantitas”. Sekarang, dengan mengetahui hal ini, kita dapat berpikir bahwa parameter Gula di kelas Kopi dapat direpresentasikan sebagai Opsional. Sekilas, ini sepertinya ide yang bagus karena, secara teori, gula tidak perlu ada dalam kopi. Namun, di sinilah saya ingin menyampaikan kapan tidak menggunakan Opsional. Kita harus menghindari penggunaan Opsional dalam skenario berikut:
  • Sebagai tipe parameter untuk POJO , seperti DTO . Opsional tidak dapat diserialisasi, jadi menggunakannya dalam POJO membuat objek tidak dapat diserialisasi.

  • Sebagai argumen metode. Jika argumen metode dapat berupa null , maka dari perspektif kode murni, meneruskan null masih lebih baik daripada meneruskan Opsional. Selain itu, Anda dapat membuat metode yang kelebihan beban untuk menangani secara abstrak tidak adanya argumen metode nol.

  • Untuk mewakili objek Koleksi yang hilang. Koleksi bisa kosong, jadi Collection yang kosong , seperti Set atau List yang kosong , harus digunakan untuk mewakili Koleksi tanpa nilai.

Kesimpulan

Opsional telah menjadi tambahan yang kuat untuk perpustakaan Java. Ini menyediakan cara untuk menangani objek yang mungkin tidak ada. Oleh karena itu, hal ini harus diperhitungkan ketika mengembangkan metode agar tidak terjerumus ke dalam perangkap penyalahgunaan. Ya, Anda dapat menulis kode hebat yang mengimplementasikan pemeriksaan null dan penanganan null, namun komunitas Java lebih memilih menggunakan Opsional. Ini secara efektif mengkomunikasikan cara menangani nilai yang hilang, jauh lebih mudah dibaca daripada pemeriksaan Null yang berantakan, dan menghasilkan lebih sedikit bug dalam kode Anda dalam jangka panjang.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION