Java: Nesnenin boş olup olmadığı nasıl kontrol edilir?


89

Web'den görüntüleri alan bir uygulama oluşturuyorum. Görüntünün alınamaması durumunda başka bir yerel görüntü kullanılmalıdır.

Aşağıdaki satırları çalıştırmaya çalışırken:

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable.equals(null)) {
  drawable = getRandomDrawable();
}

İf (drawable.equals (null)) satırı, drawable null ise bir istisna atar.

Null olması durumunda bir istisna atılmaması ve yerel görüntüyü almaması için drawable değerinin nasıl kontrol edilmesi gerektiğini bilen var mı (execute drawable = getRandomDrawable ())?


23
If (drawable == null) Kullanın Bir NULL nesnesinde herhangi bir yöntemi çağırmak bir NullPointerException'dır.
diciu

3
Neden yorum yerine normal bir cevap yazmıyorsun, diciu?
deamon

@JaredBurrows Sorudaki kodu, sorunun amacını bozacak şekilde düzenlemeyin!
Gilles 'SO- kötü olmayı bırak'

@Gilles Editör yorumumu oku, kodu daha okunaklı yaptım.
Jared Burrows

@JaredBurrows Hayır, düzenlemeniz "biçimlendirme" değişikliği değildi. Sorunun amacı olan çalışmayan kodu, soruyu tartışmalı hale getiren çalışma koduna dönüştürdünüz.
Gilles 'SO- kötü olmayı bırak'

Yanıtlar:


35

Düzenlenmiş Java 8 Çözümü:

final Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
        .orElseGet(() -> getRandomDrawable());

drawable finalBu durumda beyan edebilirsiniz .

Chasmo'nun belirttiği gibi, Android şu anda Java 8'i desteklemiyor. Dolayısıyla bu çözüm ancak başka bağlamlarda mümkündür.


7
Muhtemelen iyi bir fikir değil - şartın her iki tarafının da değerlendirildiği Fortran 60'a geri dönüyorsunuz, o zaman sadece biri kullanılır. Kullanılmayan dalda herhangi bir hesaplama varsa bu kötüdür, ki bu çoğu zaman doğrudur, bu yüzden genellikle kullanışlı bir yöntem değildir. Koşulu Commonsınıfa taşıyıp bir yedek URL sağlamanıza ve sorumlulukları bir arada tutmanıza izin verirdim .
Pete Kirkham

1
Örnek şimdi tamamen Java 8'de yeniden yazılmıştır, bu nedenle çözümüm artık gereksiz değerlendirmelerden zarar görmez (@PeteKirkham'ın orijinal çözümümde belirttiği gibi).
deamon

1
Android, Java 8'i desteklemez. Yalnızca Java 7'yi destekler (kitkatınız varsa) ve yine de, yalnızca yeni sözdizimi şekerini çağıran dinamik yoktur. Bunun yanı sıra Optional.of, değerin boş olmadığını ve dolayısıyla orElseGetgereksiz olduğunu ima eder . Optional.ofNullableBu durumda kullanmalısınız .
Martin Seeler

181
Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable == null) {
    drawable = getRandomDrawable();
}

equals()Yöntemi kontrol değeri o karşılaştırır aracı eşitlik, içeriği iki nesne. Yana nullbir nesne değil, bu içeriğine Nesnenizin içeriğini karşılaştırmak çalışırken çöküyor null.

==İçin operatör kontrol eder referans iki nesneleri aslında olup olmadığını görünüyor araçlarının eşitlik, aynı nesne . Bu, nesnelerin gerçekten var olmasını gerektirmez; var olmayan iki nesne ( nullreferanslar) da eşittir.


56
Çok değerli bir ipucu eklemek istiyorum: Karşılaştırılacak dizeleriniz veya sabitleriniz varsa, bunları her zaman eşittir yan tümcesinde ilk sıraya koyun. (if ("coyote" .equals (myDogString))), (if (myDogString.equals ("coyote"))) 'dan çok daha iyidir çünkü ikinci durumda myDogString boş olabilir ve ilk durumda yapmazken bir NPE atar myDogString'in boş olup olmadığı önemli değil.
Thorsten S.

21
Yoda koşulu olarak bilinir: "eğer bir çakal ise, köpek ..."
Thomas

1
Ayrıca eklemek isterim ki, Java 7'den beri Yoda sözdizimini umursamamanıza izin veren bir Objects.equals () yöntemi var
maryokhin

22

Bu yaklaşımı kullanıyorum:

if (null == drawable) {
  //do stuff
} else {
  //other things
}

Bu şekilde, satırın okunabilirliğini artırdığını görüyorum - bir kaynak dosyadan hızlıca okuduğumda, bunun boş bir kontrol olduğunu görebiliyorum.

Neden olabilecek .equals()bir nesneyi arayamayacağınızla ilgili olarak null; Eğer (yani 'çekilebilir') sahip nesne referansı varsa olduğunu aslında null, bu öbek üzerindeki bir nesneye işaret etmez. Bu, yığın üzerinde çağrının equals()başarılı olabileceği hiçbir nesne olmadığı anlamına gelir .

İyi şanslar!


4
Ben de yanlışlıkla atamadan kendimi korumanın bir yolu olarak if (<constant> == <variable>) yapısını tercih ederim.
Scott

7

DIY

private boolean isNull(Object obj) {
    return obj == null;
}

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (isNull(drawable)) {
    drawable = getRandomDrawable();
}

6
drawable.equals(null)

Yukarıdaki satır, çekilebilir nesne üzerinde "eşittir (...)" yöntemini çağırır.

Öyleyse, çizilebilir olmadığında ve gerçek bir nesne olduğunda, her şey yolunda gider, "eşittir (null)" yöntemini çağırmak "yanlış" döndürür

Ancak "çekilebilir" boş olduğunda, boş nesnede "eşittir (...)" yöntemini çağırmak anlamına gelir, var olmayan bir nesnede bir yöntemi çağırmak anlamına gelir, böylece "NullPointerException" oluşturur

Bir nesnenin var olup olmadığını ve boş olmadığını kontrol etmek için aşağıdakileri kullanın

if(drawable == null) {
    ...
    ...
}

Yukarıdaki durumda, "drawable" referans değişkeninin boş olduğunu veya bir değer (nesnesine referans) içerdiğini kontrol ediyoruz, böylece çekilebilirlik kontrol olarak boş ise istisna atmaz.

null == null

geçerlidir.



0

NullPointerException'ı yakalamak muhtemelen biraz daha etkilidir. Yukarıdaki yöntemler, çalışma zamanının boş işaretçileri iki kez denetlediği anlamına gelir.


1
Çifte kontrol if x == nullçözümü nerede ?
deamon

İf ifadesinden sonra, nesne kullanıldığında çalışma zamanı yeniden boş gösterici olup olmadığını kontrol edecektir. Yine de bunun derleyici tarafından optimize edilip edilmediğini bilmiyorum.
Tom R

4
Bu, istisnaları kontrol akışı olarak kullanan geleneksel bilgeliğe aykırıdır.
James

1
İstisnalar, bütün bir yığın izi oluşturmaları gerektiğinden çok pahalıdır.
deamon

0

İs -null-check (deamon'un güncellemesi) için google guava kitaplıklarını kullanın

Drawable drawable = Optional.of(Common.getDrawableFromUrl(this, product.getMapPath())).or(getRandomDrawable());

Java 8'i Optionalbugün kullansanız iyi olur .
deamon

-1

Oracle Java kaynak geliştiricisine birkaç fikir vermek için :-)

Çözüm zaten .Net'te mevcut ve çok daha okunaklı!

Visual Basic .Net'te

Drawable drawable 
    = If(Common.getDrawableFromUrl(this, product.getMapPath())
        ,getRandomDrawable()
        )

C #

Drawable drawable 
    = Common.getDrawableFromUrl(this, product.getMapPath() 
        ?? getRandomDrawable();

Bu çözümler, isteğe bağlı Java çözümü olarak güçlüdür (varsayılan dize yalnızca orijinal değer boş ise değerlendirilir), lambda ifadesi kullanmadan, yalnızca yeni bir operatör ekleyerek.

Java çözümüyle farkı hızlı bir şekilde görmek için 2 Java çözümünü ekledim

Java'da İsteğe Bağlı Kullanımı

Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
        .orElseGet(() -> getRandomDrawable());

Java'da {} kullanma

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable != null)
    {
    drawable = getRandomDrawable();
    }

Şahsen, VB.Net'i seviyorum ama Java'da çözümü tercih ediyorum ?? C#ya da if {}... ya sen?

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.