Mengapa menggunakan Optional.of daripada Optional.ofNullable?

232

Saat menggunakan kelas Java 8 Optional, ada dua cara di mana nilai dapat dibungkus dalam opsional.

String foobar = <value or null>;
Optional.of(foobar);         // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException

Saya mengerti Optional.ofNullableadalah satu-satunya cara aman untuk menggunakan Optional, tetapi mengapa Optional.ofada? Mengapa tidak menggunakan saja Optional.ofNullable dan berada di sisi yang aman setiap saat?

angin puyuh
sumber
1
tolong beri tahu saya paket mana yang harus diimpor untuk menggunakan ini?
LoveToCode
4
@LoveToCode java.util.Optional- Ini tersedia jika Anda menggunakan JDK 8 atau lebih baru
whirlwin
11
Saya akan senang jika mereka mau ofNullable()menamai of()dan of()menamaiofNotNull()
Robert Niestroj
Silakan merujuk baeldung.com/java-optional
Sumesh TG
Ketika Anda bertanya, "Mengapa Optional.of ada sama sekali? Mengapa tidak menggunakan Optional.ofNullable dan berada di sisi yang aman setiap saat?" Katakanlah jika data yang diperlukan pengguna tidak ada, maka kita harus membuang pengecualian. Jadi, itu benar-benar tergantung pada usecase Anda. baeldung.com/java-optional-throw-exception
Karan Arora

Jawaban:

306

Pertanyaan Anda didasarkan pada asumsi bahwa kode yang mungkin dibuang NullPointerExceptionlebih buruk daripada kode yang tidak. Anggapan ini salah. Jika Anda berharap bahwa Anda foobartidak pernah nol karena logika program, itu jauh lebih baik untuk digunakan Optional.of(foobar)karena Anda akan melihat NullPointerExceptionyang akan menunjukkan bahwa program Anda memiliki bug. Jika Anda menggunakan Optional.ofNullable(foobar)dan foobarkebetulan nullkarena bug, maka program Anda akan terus bekerja secara tidak benar, yang mungkin merupakan bencana yang lebih besar. Dengan cara ini kesalahan dapat terjadi jauh kemudian dan akan jauh lebih sulit untuk memahami pada titik mana kesalahan itu terjadi.

Tagir Valeev
sumber
129
" Jika Anda berharap bahwa foobar Anda tidak pernah nol karena logika program, itu jauh lebih baik untuk digunakanOptional.of(foobar) ". Ini sepertinya agak aneh - ketika kita tahu bahwa nilainya tidak akan nulldalam hal apa pun, lalu mengapa tidak menggunakan nilai itu sendiri, alih-alih membungkusnya dalam suatu Optional?
Konstantin Yovkov
54
@kocko, Anda mungkin harus mengembalikan Optionaldari metode seperti yang diperlukan oleh antarmuka yang Anda laksanakan (mungkin implementator lain dapat mengembalikan opsional kosong). Atau Anda ingin membuat koleksi / aliran opsional, beberapa di antaranya dijamin bukan nol dan ada yang tidak. Atau Anda memiliki logika kondisional yang membuat opsional di beberapa cabang dan di cabang tunggal Anda yakin itu bukan nol.
Tagir Valeev
28
Karena Opsional berarti dapat hadir, atau tidak ada. Absen! = Null. nulldalam hal ini berarti "Saya berharap foobar hadir, tetapi karena bug itu nol". Optional.isPresent() == falseberarti foobar tidak ada, artinya ini diharapkan, perilaku yang sah.
Buurman
43
@kocko: contoh sederhana: return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));yang listdiharapkan tidak pernah mengandung nullnilai-nilai ...
Holger
5
@Harish jika Anda bertanya kepada saya, saya tidak menyarankan untuk menggunakan Opsional di mana-mana. Itu pertanyaan terpisah. Anda dapat memeriksa beberapa pendapat di sini .
Tagir Valeev
12

Selain itu, Jika Anda tahu kode Anda seharusnya tidak berfungsi jika objeknya nol, Anda bisa melempar pengecualian dengan menggunakan Optional.orElseThrow

String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(NullPointerException::new);
Karan Arora
sumber
1
Tetapi untuk ini, Anda dapat menggunakan yang lebih pendekString name = Objects.requireNonNull(nullName);
Holger
1
Poin bagus @ Holger, namun metode .orElse () memungkinkan pengecualian khusus yang mungkin membantu Anda lebih baik menangani aliran kontrol atau pencatatan informasi.
Nikos Stais
1
Nah, Anda bisa memberikan pesan pengecualian untuk memberikan informasi tambahan. Upaya penyesuaian lainnya, seperti menggunakan pengecualian berbeda dari NullPointerExceptionketika masalahnya jelas merupakan referensi yang nullseharusnya tidak dilakukan, akan menjadi langkah ke arah yang salah.
Holger
juga, Anda dapat menggunakan Opsional untuk melempar Pengecualian yang lebih spesifik (mis. kustom), bukan NPE, NPE terlalu umum, Anda dapat melempar sesuatu sepertinew NullNameException("meaningful msg")
Dáve
1

Ini tergantung pada skenario.

Katakanlah Anda memiliki beberapa fungsionalitas bisnis dan Anda perlu memproses sesuatu dengan nilai itu lebih lanjut tetapi memiliki nullnilai pada saat pemrosesan akan berdampak padanya.

Lalu, dalam hal itu, Anda bisa menggunakan Optional<?>.

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .map(<doSomething>)
                      .orElse("Default value in case of null");
Gautam Chaurasia
sumber
0

Opsional terutama harus digunakan untuk hasil Layanan. Dalam layanan Anda tahu apa yang Anda miliki dan mengembalikan Optional.of (someValue) jika Anda memiliki hasil dan mengembalikan Optional.empty () jika Anda tidak. Dalam hal ini, beberapa nilai tidak boleh nol dan tetap, Anda mengembalikan Opsional.

espendennis
sumber
1
Terima kasih atas edit Sumesh, tetapi "someValue" di baris terakhir yang Anda edit menjadi "some Value", merujuk variabel dalam "Optional.of (someValue)" di atas dan harus tetap someValue, saya pikir.
espendennis