object == null atau null == object?

97

Saya mendengar dari seseorang yang null == objectlebih baik daripada object == null cek

misal:

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

Apakah ada alasan atau ini mitos lain? Terimakasih atas bantuannya.

Jijoy
sumber
Dupe dari 271561 dan 1957836 (kecuali yang ini bertuliskan 'di Jawa')
Gishu
20
Jawa berbeda dari C #
Jijoy
5
Jika ada adalah keuntungan yang signifikan kinerja, maka pasti compiler akan mengoptimalkan itu ...
Andreas Dolk
Untuk nullreferensi, tindakan default harus melempar NPE. Beberapa perpustakaan bagus (seperti perpustakaan Java JDK7) memiliki metode seperti public static <T> T notNull(T obj) { if (obj == null) { throw new NullPointerException(); } else { return obj; } }. Ada juga @NonNull(atau @Nonnull?), Tapi itu akan "terhapus".
Tom Hawtin - tackline
2
null == objectdikenal sebagai kondisi Yoda .
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

140

Ini mungkin kebiasaan yang dipelajari dari C, untuk menghindari kesalahan ketik semacam ini (tunggal =bukan ganda ==):

if (object = null) {

Konvensi meletakkan konstanta di sisi kiri ==tidak benar-benar berguna di Java karena Java mengharuskan ekspresi tersebut ifdievaluasi ke suatu booleannilai, jadi kecuali jika konstanta adalah a boolean, Anda akan mendapatkan kesalahan kompilasi dengan cara apa pun Anda meletakkan argumen. (dan jika itu boolean, Anda tidak boleh menggunakannya ==...)

Laurence Gonsalves
sumber
4
yang bukan merupakan kebiasaan yang sangat berguna untuk java, karena kesalahan ketik akan mengakibatkan kesalahan kompilasi pada java
radai
11
Kecuali dalam kasus sudut tertentu. stackoverflow.com/questions/2369226/null-check-in-java/…
Chandra Sekar
3
@Chandru untuk Boolean, Anda dapat menggunakan x.booleanValue()atau !x.booleanValue(). x == trueatau x == falsedalam kondisi ekspresinya bau, IMHO.
Laurence Gonsalves
2
Dia memeriksa nol di sini. Dan ada kasus di mana dia benar-benar harus memeriksa Boolean untuk null karena null tidak benar atau salah.
Chandra Sekar
1
Membiasakan untuk menggunakan null == objecthanya untuk memastikan bahwa kita tidak menimpa objek secara tidak sengaja dengan kesalahan ketik seharusnya tidak menjadi kasus penggunaan sama sekali. Artinya, kami melatih diri kami sendiri bahwa sekarang saya menggunakan "null" dulu, tidak apa-apa, bahkan jika saya membuat kesalahan. Itu tidak berarti bahwa kode berfungsi seperti yang diharapkan. Meskipun null = objectdiberikan sebagai pengganti null == object, program tidak akan bekerja seperti yang diharapkan! Maka tidak ada gunanya mengikuti konvensi ini!
VanagaS
33

Seperti yang dikatakan orang lain, itu adalah kebiasaan yang dipelajari dari C untuk menghindari kesalahan ketik - meskipun bahkan di C saya mengharapkan kompiler yang layak pada tingkat peringatan yang cukup tinggi untuk memberikan peringatan. Seperti yang dikatakan Chandru, membandingkan dengan null di Java dengan cara ini hanya akan menimbulkan masalah jika Anda menggunakan variabel tipe Boolean(yang tidak ada dalam kode sampel). Saya akan mengatakan itu adalah situasi yang sangat langka, dan bukan situasi yang perlu diubah cara Anda menulis kode di tempat lain. (Saya tidak akan repot-repot membalik operan bahkan dalam kasus ini; jika saya berpikir cukup jernih untuk mempertimbangkan membalikkannya, saya yakin saya bisa menghitung tanda sama dengan.)

Apa yang belum disebutkan adalah bahwa banyak orang (termasuk saya sendiri) menganggap if (variable == constant)formulir lebih mudah dibaca - ini cara yang lebih alami untuk mengekspresikan diri. Ini adalah alasan untuk tidak secara membabi buta menyalin konvensi dari C. Anda harus selalu mempertanyakan praktik (seperti yang Anda lakukan di sini :) sebelum mengasumsikan bahwa apa yang mungkin berguna di satu lingkungan berguna di lingkungan lain.

Jon Skeet
sumber
3
Saya setuju dengan setiap kata yang Anda ucapkan terutama bagian "menyalin secara membabi buta". Saya sedang membaca kode sekarang dan gaya null = object sangat mengganggu saya sehingga saya mencarinya dan datang ke sini. Apa yang dipikirkan pembuat kode?
Adrian M
28

Ini tidak banyak nilainya di Java (1.5+) kecuali jika tipe objeknya adalah Boolean. Dalam hal ini, ini masih bisa berguna.

if (object = null)tidak akan menyebabkan kegagalan kompilasi di Java 1.5+ jika objek adalah Booleantetapi akan menampilkannya NullPointerExceptionsaat runtime.

Chandra Sekar
sumber
Anda mungkin bermaksud itu akan menyebabkan kegagalan kompilasi :)
vava
7
Tidak, itu tidak akan menyebabkan kesalahan kompilasi jika objeknya adalah Boolean.
Chandra Sekar
Bukankah itu sama untuk setiap tipe objek selain Boolean?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Untuk jenis non-Boolean, kode tidak akan dikompilasi karena jenis ekspresi "object = null" bukan boolean. Karena auto-boxing, itu akan dikompilasi untuk Boolean.
Chandra Sekar
Tetapi mengapa perilaku ini bagi Boolean? Ada alasannya?
Rohit Banga
9

Di Jawa tidak ada alasan yang bagus.

Beberapa jawaban lain menyatakan bahwa itu karena Anda dapat secara tidak sengaja menjadikannya tugas alih-alih persamaan. Tapi di Java, Anda harus memiliki boolean di if, jadi ini:

if (o = null)

tidak akan dikompilasi.

Satu-satunya saat ini bisa menjadi masalah di Java adalah jika variabelnya adalah boolean:

int m1(boolean x)
{
    if (x = true)  // oops, assignment instead of equality
R Samuel Klatchko
sumber
4
Tapi mengapa Anda pernah menulis == trueatau sama == true == true.
Tom Hawtin - tackline
7
Tidak ada alasan bagus untuk menulis == true. Tetapi saya telah melihat begitu banyak kode buruk dalam karir saya sehingga saya tidak lagi bertanya mengapa seseorang menulis sesuatu dan hanya menerima bahwa beberapa orang menulis kode yang tidak perlu / dipertanyakan.
R Samuel Klatchko
1
Memang, ada banyak kode buruk berkeliaran, tetap saja, ketika dianggap x == trueburuk karena bisa salah ditulis sebagai x = true, tidak ada gunanya mengubahnya menjadi true == xdaripada hanya x.
Holger
9

Ini juga terkait erat dengan:

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

yang nyaman jika Anda tidak ingin berurusan dengan NPE:

if (bar!=null && bar.equals("foo")) {
cherouvim
sumber
mungkin nyaman tetapi bisa berbahaya blue-walrus.com/2010/11/…
Oliver Watkins
@OliverWatkins: Saya menemukan artikel ini lemah. Asumsikan variabel itu berjenis int. Jika tidak diinisialisasi, nilainya menjadi 0 dan janji artikel tidak akan berlaku. Fakta bahwa String adalah objek dan int adalah primitif tidak relevan dengan fakta bahwa programmer mungkin lupa memasukkan variabel. Dalam pertanyaan ini kita hanya menyelesaikan hal perbandingan String null.
cherouvim
@cherouvim fakta bahwa intadalah tipe primitif adalah relevan, karena tidak mungkin untuk memohon equalspada int, maka, tidak ada gunanya membahas cuaca untuk digunakan x.equals(constant)atau constant.equals(x)untuk intnilai-nilai. Dan untuk Integernilai-nilai, nilai default adalah nullbukan 0.
Holger
5

Trik ini dimaksudkan untuk mencegah salah v = nullketik.

Tetapi Java hanya mengizinkan ekspresi boolean sebagai if()kondisi sehingga trik tidak masuk akal, compiler akan tetap menemukan kesalahan ketik tersebut.

Ini masih trik yang berharga untuk kode C / C ++.

vava
sumber
3

Untuk alasan yang sama Anda melakukannya di C; assignment adalah ekspresi, jadi Anda meletakkan literal di sebelah kiri sehingga Anda tidak dapat menimpanya jika Anda tidak sengaja menggunakannya, =bukan ==.

Ignacio Vazquez-Abrams
sumber
Ini hanya masalah di Java untuk tipe boolean, bukan? Jenis tugas lainnya tidak akan memiliki tipe boolean, dan akan menyebabkan kesalahan kompilator.
Scott Smith
1
tidak, compiler Java akan menangkap kesalahan ketik semacam itu sesuai urutan yang Anda inginkan
vava
@ Jijoy - Saya tidak berpikir ini ada hubungannya dengan kinerja. Ini terdengar seperti trik lama di C untuk menghindari kesalahan penugasan-dalam-ekspresi-bersyarat yang ditakuti. Idenya adalah jika Anda mencoba untuk memeriksa untuk melihat apakah xsama 5, ketika Anda salah mengetik if (x = 5), itu akan dikompilasi secara diam-diam (dan selalu mengevaluasi true, terlepas dari nilai x). Namun, jika Anda terbiasa untuk selalu menentukan literal terlebih dahulu: 'if (5 = x)', kompilator dapat memeriksa ulang pekerjaan Anda dan menghemat waktu head banging di debugger. Penyusun modern membuat kebiasaan ini tidak perlu.
Scott Smith
6
-1: Jika Anda tidak sengaja menggunakan = itu tidak dapat dikompilasi di Java; jadi alasan dari C tidak berlaku.
Jon Skeet
Secara teknis jika objtipe java.lang.Boolean(B besar), maka itu bisa membuat perbedaan (saya pikir, tidak benar-benar mencoba atau apa pun).
Tom Hawtin - tackline
3

Itu untuk orang yang lebih suka memiliki konstanta di sisi kiri. Dalam kebanyakan kasus, memiliki konstanta di sisi kiri akan mencegah NullPointerException dilempar (atau memiliki nullcheck lain). Misalnya metode String sama dengan melakukan pemeriksaan nol. Memiliki konstanta di sebelah kiri, akan mencegah Anda menulis cek tambahan. Yang mana, cara lain juga dilakukan nanti. Memiliki nilai nol di sebelah kiri hanya menjadi konsisten.

Suka:

 String b = null;
 "constant".equals(b);  // result to false
 b.equals("constant");  // NullPointerException
 b != null && b.equals("constant");  // result to false
SPee
sumber
penyembunyian NPE ini semakin mempersulit pencarian bug di bagian hilir
Oliver Watkins
2

Ini adalah kondisi Yoda yang menulis dengan cara yang berbeda

Di java

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

kondisi yoda

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

Bandingkan dengan kode berikut:

    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 );

Output (Setelah beberapa eksekusi):

null != pingResult
325737
pingResult != null
47027

Oleh karena itu, pingResult != nulladalah pemenangnya.

Avinash
sumber
7
Jalankan pengujian Anda dalam putaran tambahan! Atau ganti saja pernyataan IF. Singkat cerita: tidak ada perbedaan! Loop pertama selalu lebih lambat.
Marcel Jaeschke
Dalam pengujian ini, pingResult selalu bukan null. Apa yang terjadi dengan waktu pingResult null? Saya bertaruh itu platform independen, tetapi pada tumpukan Oracle Java 1.6 / Linux saya, hasilnya cukup banyak (dalam satu lingkaran), kecuali jika pingResult adalah null, kedua pemeriksaan itu beberapa persen lebih cepat.
Ogre Mazmur33
1
jika Anda meletakkan "pingResult! = null block sebelum null! = pingResult block, itu akan menghasilkan sesuatu seperti" pingResult! = null 325737 "
Sola Yang
Seperti yang dikatakan @Sola Yang, jika Anda meletakkan pingResult! = Null sebelumnya, Anda akan melihat bahwa itu membutuhkan lebih banyak waktu daripada null! = PingResult. Jika pingResult! = Null lebih cepat dari null! = PingResult IDE (seperti IntelliG, Eclipse, ...) akan membuat peringatan untuk memaksa pengembang menggunakan peran ini;)
adil.hilmi
1

Karena sifat komutatifnya , satu-satunya perbedaan antara object == nulldan null == object( versi Yoda ) adalah pada sifat kognitif : bagaimana kode dibaca dan dicerna oleh pembaca. Saya tidak tahu jawaban pasti, tapi saya tahu saya secara pribadi lebih suka membandingkan objek yang saya periksa dengan sesuatu yang lain, daripada membandingkan sesuatu yang lain dengan objek yang saya periksa , jika itu masuk akal. Mulailah dengan subjeknya, lalu nilai untuk membandingkannya.

Dalam beberapa bahasa lain gaya perbandingan ini lebih berguna.

Untuk melindungi dari tanda "=" yang hilang secara umum, menurut saya menulis null == objectadalah tindakan pemrograman defensif yang salah arah . Cara yang lebih baik untuk mengatasi kode khusus ini adalah dengan menjamin perilakunya dengan uji junit. Ingat, kemungkinan kesalahan kehilangan "=" tidak bergantung pada argumen input metode - Anda tidak bergantung pada penggunaan yang benar dari API ini oleh orang lain - jadi pengujian junit sempurna untuk melindungi dari itu. Bagaimanapun Anda akan ingin menulis tes junit untuk memverifikasi perilaku; "=" yang hilang secara alami berada dalam cakupan.

Benny Bottema
sumber