nesne == null veya null == nesne?


97

Kontrol null == objectetmekten daha iyi birinden duydumobject == null

Örneğin :

void m1(Object obj ) {
   if(null == obj)  // Is this better than object == null ? Why ?
       return ;
   // Else blah blah
}

Herhangi bir sebep var mı yoksa bu başka bir efsane mi? Yardım için teşekkürler.


271561 ve 1957836'nın tekrarı (bunun 'Java'da' yazması dışında)
Gishu

20
Java, C #
Jijoy'dan farklıdır

5
Orada ise oldu önemli bir performans avantajı, daha sonra kesin derleyici ... optimize olacaktır
Andreas Dolk

İçin nullbaşvurular, eylemin varsayılan ders NPE atmak olmalıdır. Bazı güzel kitaplıkların (JDK7 Java kitaplığı gibi) bir yöntemi vardır public static <T> T notNull(T obj) { if (obj == null) { throw new NullPointerException(); } else { return obj; } }. Ayrıca @NonNull(veya @Nonnull?) Vardır , ancak bu "silinir".
Tom Hawtin - tackline

Yanıtlar:


140

Bu, bu tür bir yazım hatasından kaçınmak için muhtemelen C'den öğrenilen bir alışkanlıktır (çift =yerine tek ==):

if (object = null) {

Sabiti'nin sol tarafına koyma kuralı ==Java'da pek kullanışlı değildir çünkü Java, ifadenin ifbir booleandeğer olarak değerlendirilmesini gerektirir , bu nedenle sabit a değilse, booleanher iki şekilde de bir derleme hatası alırsınız. argümanlar. (ve eğer bir boole ise, ==yine de kullanmamalısınız ...)


4
Bu java için pek kullanışlı bir alışkanlık değil, çünkü yazım hatası
java'da


3
Boolean için @Chandru, x.booleanValue()veya kullanabilirsiniz !x.booleanValue(). x == trueveya x == falsebir koşulda ifade kötü bir koku, IMHO.
Laurence Gonsalves

2
Burada boşluğu kontrol ediyor. Ve null ne doğru ne de yanlış olduğu için bir Boolean null için gerçekten kontrol etmesi gereken durumlar vardır.
Chandra Sekar

1
null == objectBir yazım hatası ile yanlışlıkla nesnenin üzerine yazmadığımızdan emin olmak için kullanmaya alışmak , hiç de bir kullanım alanı olmamalıdır. Bu da demek oluyor ki, artık önce "boş" kullandığım için kendimizi eğitiyoruz, bir hata yapsam bile sorun değil. Bu, kodun beklendiği gibi çalıştığı anlamına gelmez. null = objectYerine verilse bile null == objectprogram beklendiği gibi çalışmayacaktır! O halde bu sözleşmeye uymanın bir anlamı yok!
VanagaS

33

Diğerlerinin de söylediği gibi, yazım hatalarını önlemek C'den öğrenilen bir alışkanlıktır - ancak C'de bile, yeterince yüksek uyarı seviyelerine sahip iyi derleyicilerden bir uyarı vermelerini beklerdim. Chandru'nun dediği gibi, Java'da null ile bu şekilde karşılaştırma, yalnızca bir değişken türü Boolean(örnek kodda olmadığınız) kullanıyorsanız sorunlara neden olur . Bunun oldukça nadir bir durum olduğunu söyleyebilirim ve her yerde kod yazma şeklinizi değiştirmeye değecek bir durum değil. (Bu durumda bile işlenenleri tersine çevirme zahmetine girmem; eğer onları ters çevirmeyi düşünecek kadar net düşünüyorsam, eminim eşittir işaretlerini sayabilirim.)

Ne henüz söz edilmiştir birçok kişi (ben kesinlikle dahil) bulmandır if (variable == constant)o kendini ifade daha doğal bir yoldur - daha okunabilir olması için formu. Bu bir nedendir değil (her zaman soru uygulamaları gerektiğini burada ne aradığını :) tek bir ortamda yararlı olabilir Ne olduğunu varsayarak önceki gibi başka yararlıdır körü körüne C. Sizden bir kongre kopyalamak için.


3
Söylediğin her kelimeye, özellikle de "kongreyi körü körüne kopyala" kısmını kabul ediyorum. Şu anda bir kod okuyorum ve null = nesne stili beni o kadar rahatsız ediyor ki, ona baktım ve buraya geldim. Kodlayıcı ne düşünüyordu?
Adrian M

28

Bu, nesnenin türünün olduğu durumlar dışında Java'da (1.5+) çok değerli değildir Boolean. Bu durumda, bu yine de kullanışlı olabilir.

if (object = null)nesne ise Java 1.5+ sürümünde derleme hatasına neden Booleanolmaz , ancak NullPointerExceptionçalışma zamanında bir hata verir .


Muhtemelen derleme hatasına neden olacağını kastettiniz :)
vava

7
Hayır, nesne Boole olduğunda bir derleme hatasına neden olmaz.
Chandra Sekar

Boole dışında her nesne türü için aynı değil mi?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
Boole olmayan türler için, "nesne = null" ifadesinin türü boole olmayacağından kod derlenmez. Otomatik kutulama nedeniyle Boolean için derlenecektir.
Chandra Sekar

Ama neden Boolean için bu davranış? Gerekçe var mı?
Rohit Banga

9

Java'da iyi bir neden yok.

Diğer birkaç cevap, bunun, eşitlik yerine yanlışlıkla onu atama yapabileceğiniz için olduğunu iddia etti. Ancak Java'da, if'de boolean olması gerekir, bu yüzden bu:

if (o = null)

derlenmeyecek.

Bunun Java'da önemli olabileceği tek durum, değişkenin boole olmasıdır:

int m1(boolean x)
{
    if (x = true)  // oops, assignment instead of equality

4
Ama neden hiç yazasın == trueya da eşit olarak == true == true.
Tom Hawtin -

7
Yazmak için iyi bir sebep yok == true. Ama kariyerimde o kadar çok kötü kod gördüm ki artık birisinin neden bir şeyler yazacağını sormuyorum ve sadece bazılarının gereksiz / sorgulanabilir kod yazdığını kabul ediyorum.
R Samuel Klatchko

1
Aslında, etrafta uçuşan çok sayıda kötü kod var, yine x == truede kötü olduğu düşünüldüğünde , çünkü yanlış yazılabileceği için x = true, onu true == xsadece yerine değiştirmenin pek bir anlamı olmayacaktı x.
Holger

9

Bu aynı zamanda aşağıdakilerle de yakından ilgilidir:

if ("foo".equals(bar)) {

NPE'lerle uğraşmak istemiyorsanız kullanışlıdır:

if (bar!=null && bar.equals("foo")) {

uygun olabilir ama tehlikeli olabilir blue-walrus.com/2010/11/…
Oliver Watkins

@OliverWatkins: Bu makaleyi zayıf buluyorum. Değişkenin int türünde olduğunu varsayın. İlklendirilmemiş bırakılırsa, değer 0 olur ve makalenin sözü tutmaz. Dizelerin nesneler ve intlerin ilkel olmaları gerçeği, bir programcının bir değişkeni başlatmayı unutması gerçeğiyle ilgisizdir. Bu soruda null String karşılaştırma meselesini çözüyoruz.
cherouvim

@cherouvim, intilkel bir tür olduğu gerçeği ile ilgilidir, çünkü equalsbir üzerinde başvurmak imkansızdır int, bu nedenle, kullanmak için x.equals(constant)veya değerler constant.equals(x)için tartışmanın bir anlamı yoktur int. Ve yönelik Integerdeğerler, varsayılan değerdir nullziyade 0.
Holger

5

Bu numara bir v = nulltür yazım hatalarını önlemiş olmalı .

Ancak Java, if()koşul olarak yalnızca boole ifadelerine izin verir, bu yüzden hile pek bir anlam ifade etmez, derleyici yine de bu yazım hatalarını bulacaktır.

Yine de C / C ++ kodu için hala değerli bir numaradır.


3

Aynı sebepten dolayı C'de yaparsınız; atama bir ifadedir, bu nedenle harfi harfine sola koyarsınız, böylece yanlışlıkla =yerine kullanırsanız üzerine yazamazsınız ==.


Bu yalnızca mantıksal türler için Java'da bir sorundur, değil mi? Diğer herhangi bir atama türünde boolean türü olmaz ve derleyici hatasına neden olur.
Scott Smith

1
hayır, Java derleyicisi bu tür bir yazım
hatasını

@Jijoy - Bunun performansla ilgisi olduğunu sanmıyorum. Bu, koşullu ifade içinde korkunç atama hatasından kaçınmak için C'de eski bir numara gibi geliyor. Buradaki fikir şuydu: xEşit olup olmadığını kontrol etmeye çalışıyorsanız 5, yanlışlıkla if (x = 5)yazdığınızda, sessizce derlenecek (ve truedeğerine bakılmaksızın her zaman değerlendirilecek x). Bununla birlikte, her zaman ilk önce değişmezi belirtme alışkanlığını edinirseniz: 'if (5 = x)', derleyici çalışmanızı iki kez kontrol edebilir ve hata ayıklayıcıda sizi baştan çıkarıcı zaman kazandırabilir. Modern derleyiciler bu alışkanlığı gereksiz kılıyor.
Scott Smith

6
-1: Yanlışlıkla = kullanırsanız, Java'da derlenmez; bu nedenle C'nin nedeni geçerli değildir.
Jon Skeet

Teknik olarak objÇeşidi oldu java.lang.Boolean(büyük B), o zaman (Ben aslında denenmiş ya da bir şey düşünmek) bir fark yaratabilir.
Tom Hawtin - tackline

3

Bu, sol tarafta sabit olmasını tercih eden insanlar içindir. Çoğu durumda, sabitin sol tarafta olması NullPointerException'ın atılmasını (veya başka bir nullcheck olmasını) engeller. Örneğin, String yöntemi şuna eşittir ayrıca bir null denetimi yapar. Sabit değerin solda olması, ek çek yazmanızı engeller. Hangisi, başka bir şekilde daha sonra da yapılır. Soldaki boş değere sahip olmak sadece tutarlıdır.

sevmek:

 String b = null;
 "constant".equals(b);  // result to false
 b.equals("constant");  // NullPointerException
 b != null && b.equals("constant");  // result to false

NPE'nin bu şekilde gizlenmesi, aşağı akışta böcek bulmayı daha da zorlaştırıyor
Oliver Watkins

2

Yoda koşulunun farklı bir şekilde yazılmasıdır

Java'da

String myString = null;
if (myString.equals("foobar")) { /* ... */ } //Will give u null pointer

yoda durumu

String myString = null;
if ("foobar".equals(myString)) { /* ... */ } // will be false 

1

Aşağıdaki kodla karşılaştırın:

    String pingResult = "asd";
    long s = System.nanoTime ( );
    if ( null != pingResult )
    {
        System.out.println ( "null != pingResult" );
    }
    long e = System.nanoTime ( );
    System.out.println ( e - s );

    long s1 = System.nanoTime ( );
    if ( pingResult != null )
    {
        System.out.println ( "pingResult != null" );
    }
    long e1 = System.nanoTime ( );
    System.out.println ( e1 - s1 );

Çıktı (Birden fazla yürütmeden sonra):

null != pingResult
325737
pingResult != null
47027

Bu nedenle, pingResult != nullkazanır.


7
Testinizi ek bir döngüde çalıştırın! Ya da sadece IF ifadelerini değiştirin. Uzun lafın kısası: hiçbir fark yok! İlk döngü her zaman daha yavaştır.
Marcel Jaeschke

Bu testte, pingResult her zaman boş değildir. PingResult'un zamanlamasına ne olur null? Bahse girerim, platformdan bağımsızdır, ancak benim Oracle Java 1.6 / Linux yığınımda sonuçlar hemen hemen eşittir (bir döngüde), ancak pingResult boş ise, her iki kontrol de yüzde birkaç daha hızlıdır.
Ogre Mezmur 33

1
"pingResult! = null bloğu null! = pingResult bloğundan önce koyarsanız," pingResult! = null 325737 "
Sola Yang

@Sola Yang'ın dediği gibi, daha önce pingResult! = Null koyarsanız, bunun null! = PingResult'dan daha fazla zaman aldığını göreceksiniz. PingResult! = Null, null'dan daha hızlıysa! = PingResult IDE (IntelliG, Eclipse, ... gibi) geliştiricileri bu rolü kullanmaya zorlamak için bir uyarıda bulunacaktır;)
adil.hilmi

1

Değişme özelliği nedeniyle, object == nullve null == object( Yoda versiyonu ) arasındaki tek fark bilişsel niteliktedir : kodun okuyucu tarafından nasıl okunduğu ve sindirildiği. Yine de kesin cevabı bilmiyorum, ama kişisel olarak incelediğim nesneyi başka bir şeyle karşılaştırmayı tercih ettiğimi biliyorum , eğer mantıklıysa, incelediğim nesneyle başka bir şeyi karşılaştırmak yerine . Konuyla başlayın, ardından onu karşılaştırılacak değerle başlayın.

Diğer bazı dillerde bu karşılaştırma stili daha kullanışlıdır.

Genel olarak eksik bir "=" işaretine karşı korunmak için, yazmanın null == objectyanlış bir savunma programlama eylemi olduğunu düşünüyorum . Bu özel kodun etrafından dolaşmanın daha iyi yolu, davranışı bir junit testi ile garanti etmektir. Unutmayın, olası bir "=" hatası, yöntemin girdi argümanlarına bağlı değildir - bu API'nin başkaları tarafından doğru kullanımına bağlı değilsiniz - bu nedenle, bunun yerine bir junit testi, buna karşı korunmak için mükemmeldir. Her neyse, davranışı doğrulamak için junit testleri yazmak isteyeceksiniz; eksik bir "=" doğal olarak kapsam dahilindedir.

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.