Neden Optional.of yerine Optional.ofNullable kullanıyorsunuz?


232

Java 8 Optionalsınıfını kullanırken, bir değerin isteğe bağlı olarak sarılabilmesinin iki yolu vardır.

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

Anlamanın Optional.ofNullabletek güvenli yolu olduğunu anlıyorum Optional, ama neden hiç Optional.ofvar? Neden her zaman sadece Optional.ofNullable güvenli tarafta olmak değil ?


1
lütfen bunu kullanmak için hangi paketin içe aktarılması gerektiğini söyle?
LoveToCode

4
@LoveToCode java.util.Optional- JDK 8 veya daha yenisini kullanıyorsanız kullanılabilir
whirlwin

11
Onlar ofNullable()adlandırılmış of()ve of()adlandırılmış ofNotNull()
isterdim


"Optional.of neden var? Neden sadece Optional.ofNullable 'ı kullanmıyorsunuz ve her zaman güvenli tarafta olmuyorsunuz?" Diyelim ki kullanıcının gerekli verileri mevcut değilse, istisna atmalıyız. Yani, tamamen sizin kullanımınıza bağlıdır. baeldung.com/java-optional-throw-exception
Karan Arora

Yanıtlar:


306

Sorunuz fırlatabilecek NullPointerExceptionkodun yapamayan koddan daha kötü olduğu varsayımına dayanmaktadır . Bu varsayım yanlış. foobarProgram mantığı nedeniyle hiçbir zaman boş kalmamanızı bekliyorsanız, programınızın bir hata olduğunu gösteren Optional.of(foobar)bir tane göreceğiniz için kullanmak çok daha iyidir NullPointerException. Eğer kullanıyorsanız Optional.ofNullable(foobar)ve foobarolur nulldolayı hatadan sonra program sessizce büyük bir felaket olabilen hatalı çalışmaya devam edecektir. Bu şekilde daha sonra bir hata meydana gelebilir ve hangi noktada yanlış gittiğini anlamak çok daha zor olur.


129
" Program mantığından dolayı foobar'ınızın asla boş kalmamasını bekliyorsanız, kullanmak çok daha iyidirOptional.of(foobar) ". Bu biraz garip görünüyor - değerin nullher durumda olmayacağını bildiğimizde, neden değerin kendisini içine sarmak yerine kullanmıyorsunuz Optional?
Konstantin Yovkov

54
@kocko, Optionaluyguladığınız arabirimin gerektirdiği şekilde yöntemden döndürmeniz gerekebilir (muhtemelen diğer uygulayıcılar boş bir isteğe bağlı döndürebilir). Ya da bazıları null olmayan ve bazıları garanti edilmeyen opsiyonel bir koleksiyon / akış oluşturmak istersiniz. Ya da birkaç dalda isteğe bağlı oluşturan koşullu mantığınız var ve tek dalda bunun boş olmadığından emin olabilirsiniz.
Tagir Valeev

28
Çünkü Opsiyonel, mevcut ya da yok olabileceği anlamına gelir. Yok! = Boş. nullbu durumda "fobarın mevcut olmasını bekliyorum, ancak bir hata nedeniyle boş" anlamına gelir. Optional.isPresent() == falsefoobar olmadığı anlamına gelir, yani bu beklenen, meşru davranış.
Buurman

43
@kocko: Basit bir örnek: içermesi asla bekleniyor ... değerlerinireturn list.isEmpty()? Optional.empty(): Optional.of(list.get(0));listnull
Holger

5
@Harish bana soruyorsanız, her yerde Optionals kullanmanızı önermiyorum. Bu ayrı bir soru. Burada bazı görüşleri kontrol edebilirsiniz .
Tagir Valeev

12

Ayrıca, nesne null olduğunda kodunuzun çalışmaması gerektiğini biliyorsanız, şunu kullanarak özel durum atabilirsiniz: Optional.orElseThrow

String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(NullPointerException::new);

1
Ancak bunun için daha da kısa kullanabilirsinizString name = Objects.requireNonNull(nullName);
Holger

1
İyi nokta @Holger, ancak .orElse () yöntemi, denetim akışını veya bilgi günlüğünü daha iyi işlemenize yardımcı olabilecek özel özel durumlara izin verir.
Nikos Stais

1
Ek bilgi vermek için istisna için bir mesaj verebilirsiniz. NullPointerExceptionSorunun açıkça nullgörülmemesi gereken bir referans olduğu zamandan farklı bir istisna kullanmak gibi başka bir özelleştirme girişimi , yanlış yöne doğru bir adım olacaktır.
Holger

ayrıca, NPE değil, daha spesifik (örn. özel) İstisna atmak için İsteğe new NullNameException("meaningful msg")
Bağlı'yı

1

Bu senaryolara bağlıdır.

Diyelim ki bazı işlevsellik işlevleriniz var ve bu değere sahip bir şeyi daha fazla işlemeniz gerekiyor, ancak nullişleme sırasında değere sahip olmak onu etkileyecektir.

Sonra, bu durumda kullanabilirsiniz Optional<?>.

String nullName = null;

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

0

İsteğe bağlı olarak, yine de Hizmetlerin sonuçları için kullanılmalıdır. Hizmette elinizde ne olduğunu bilirsiniz ve bir sonucunuz varsa Optional.of (someValue) değerini döndürürseniz, yoksa Optional.empty () öğesini döndürürsünüz. Bu durumda, bazı değerler asla boş olmamalıdır ve yine de bir İsteğe bağlı döndürürsünüz.


1
Düzenleme Sumesh için teşekkürler, ama "bazı Değer" olarak düzenlenmiş son satırında "someValue", yukarıdaki "Optional.of (someValue)" değişken başvurular ve someValue kalmak gerekir, sanırım.
espendennis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.