Periksa apakah null Boolean benar menghasilkan pengecualian


169

Saya memiliki kode berikut:

Boolean bool = null;

try 
{
    if (bool)
    {
        //DoSomething
    }                   
} 
catch (Exception e) 
{
    System.out.println(e.getMessage());             
}

Mengapa pemeriksaan saya pada variabel Boolean "bool" menghasilkan pengecualian? Tidakkah seharusnya itu hanya melewati pernyataan if ketika "melihat" bahwa itu tidak benar? Ketika saya menghapus pernyataan if atau mengecek apakah itu BUKAN nol, pengecualian hilang.


3
Jawaban di atas tentang objek unboxing semuanya benar. Namun, demi kelengkapan, Anda juga dapat mengubah kode Anda untuk menggunakan "boolean" primitif alih-alih pembungkus objek "Boolean". Anda juga harus menyegarkan diri sendiri tentang perbedaan antara primitif dan Obyek.
Marvo

Sementara itu ... if (bool == Boolean.TRUE)mengevaluasi false tanpa menghasilkan pengecualian. Tidak yakin apakah ini disengaja dalam kasus yang baru saja saya temukan.
simon.watts

2
@ simon.watts yang akan salah untuk boolmenjadi nullOR jika Booleandibangun secara eksplisit (dan bukan sebagai referensi Boolean.TRUE). Jadi tidak direkomendasikan; sebagai lawan if (Boolean.TRUE.equals(bool))yang akan bekerja seperti yang diharapkan, termasuk nullnilai penanganan yang aman .
StaxMan

Jawaban:


171

Ketika Anda memilikinya booleandapat berupa trueatau false. Namun ketika Anda memilikinya Booleandapat berupa Boolean.TRUE, Boolean.FALSEatau nullsebagai objek lain.

Dalam kasus khusus Anda, Booleanis nulldan ifpernyataan Anda memicu konversi implisit ke booleanyang menghasilkan NullPointerException. Anda mungkin perlu:

if(bool != null && bool) { ... }

23
Secara teknis a Booleandapat berupa jumlah instance yang benar, bukan hanya Boolean.TRUE. Sebagai contoh new Boolean(true).
Steve Kuo

1
Aku berjuang untuk memahami mengapa if (myBoolean)(di mana myBooleanadalah Boolean) tidak menaikkan kesalahan kompilator atau setidaknya peringatan. Ini pasti mengerti.
Josh M.

1
@ Josh. Ini karena Java melakukan Boxing and Unboxing of wrappers: docs.oracle.com/javase/tutorial/java/data/autoboxing.html
Vinicius

3
@Vinicius yakin, tetapi kompiler harus melakukan null untuk kita dalam kasus ini, setidaknya melalui peringatan kompiler.
Josh M.

2
@ Josh. Tidak bisa setuju lebih banyak :)
Vinicius

402

Jika Anda tidak menyukai cek null tambahan:

if (Boolean.TRUE.equals(value)) {...}

1
@ AvrDragon: apakah diperlukan yang sama? Operator == bekerja di sini karena Boolean hanya memiliki dua nilai
Atul

7
@ Bibul Ya, sama diperlukan di sini. Karena (Boolean baru (benar) == Boolean baru (benar)) adalah .... false. Alasan: Boolean hanyalah sebuah kelas dan dapat memiliki banyak instance seperti kelas lain di java.
AvrDragon

35
ya, itu memalukan, konstruktornya harus pribadi sehingga dipastikan itu twingleton ...
fortran

15
@fortran +1 untuk "twingleton".
Bennett McElwee

1
Sama sekali tidak ada gunanya menggunakan Apache BooleanUtils atas idiom ini.
StaxMan

82

Gunakan Apache BooleanUtils .

(Jika kinerja puncak adalah prioritas paling penting dalam proyek Anda, maka lihat salah satu jawaban lain untuk solusi asli yang tidak memerlukan termasuk perpustakaan eksternal.)

Jangan menemukan kembali roda. Leverage apa yang sudah dibangun dan digunakan isTrue():

BooleanUtils.isTrue( bool );

Memeriksa apakah suatu Booleannilai benar, menangani nulldengan mengembalikan false.

Jika Anda tidak terbatas pada perpustakaan yang "diizinkan" untuk Anda sertakan, ada banyak fungsi pembantu yang bagus untuk semua jenis use case, termasuk Booleansdan Strings. Saya sarankan Anda membaca berbagai perpustakaan Apache dan melihat apa yang sudah mereka tawarkan.


59
Menemukan kembali roda tidak tampak begitu buruk ketika alternatifnya menggunakan perpustakaan eksternal untuk sesuatu yang mendasar seperti ini.
Paul Manta

3
@ PaulManta Saya setuju jika ini adalah satu-satunya hal yang pernah Anda gunakan di perpustakaan Apache Utils, tetapi ide yang disarankan adalah "membaca dengan teliti" perpustakaan untuk mengekspos diri Anda ke fungsi-fungsi bermanfaat lainnya.
Joshua Pinter

1
Ada penalti kinerja untuk menggunakan perpustakaan ini. Jadi untuk hal-hal dasar seperti itu yang merupakan bagian dari bahasa, Anda tidak boleh menggunakan perpustakaan.
ACV

6
Itu perpustakaan menciptakan kembali roda. Saya berusaha menghindari perpustakaan seperti itu sebanyak mungkin.
mschonaker

3
@mschonaker Jika Apache BooleanUtils menciptakan kembali roda, apa roda aslinya ? Idenya adalah untuk menghindari membuat banyak fungsi pembantu yang meniru apa yang sudah dilakukan di perpustakaan seperti ini. Saya juga menggunakan toStringYesNodari perpustakaan ini di semua aplikasi saya.
Joshua Pinter

13

Booleanjenis bisa null. Anda perlu melakukan nullpemeriksaan seperti yang telah Anda tetapkan null.

if (bool != null && bool)
{
  //DoSomething
}                   

3
Apa yang salah dengan jawaban ini? Bukan pengecekan bool yang akan melempar pengecualian. Downvotes yang tidak perlu.
dodexahedron

2
Saya setuju itu jawaban yang sangat masuk akal. Anda bisa menyingkirkan penanganan pengecualian.
Marvo

14
Menyerahkan perkecualian tidak perlu, dan di samping itu dilakukan dengan cara yang merupakan contoh buruk bagi pemula. Ini layak untuk downvote, IMO. (Ya ... Saya tahu itu berasal dari kode contoh, tetapi mengulanginya dalam Jawaban tampaknya mendukungnya.)
Stephen C

1
Lalu apa yang BENAR? Saya tidak melihat jawaban Anda di sini.
Marvo

5
Cara yang benar adalah yang di atas..tidak ada penanganan pengecualian. Juga, penanganan Pengecualian terlalu umum dan tidak disarankan.
vellvisher

8

Atau dengan kekuatan Java 8 Opsional, Anda juga dapat melakukan trik seperti itu:

Optional.ofNullable(boolValue).orElse(false)

:)


5

Boolean adalah kelas objek pembungkus untuk boolean primitif. Kelas ini, seperti kelas apa pun, memang bisa nol. Untuk alasan kinerja dan memori, yang terbaik adalah selalu menggunakan primitif.

Kelas wrapper di Java API melayani dua tujuan utama:

  1. Untuk menyediakan mekanisme untuk "membungkus" nilai-nilai primitif dalam suatu objek sehingga primitif dapat dimasukkan dalam kegiatan yang disediakan untuk objek, seperti ditambahkan ke Koleksi, atau dikembalikan dari metode dengan nilai pengembalian objek.
  2. Untuk menyediakan berbagai macam fungsi utilitas untuk primitif. Sebagian besar fungsi ini terkait dengan berbagai konversi: mengkonversi primitif ke dan dari objek String, dan mengkonversi primitif dan objek String ke dan dari pangkalan yang berbeda (atau radix), seperti biner, oktal, dan heksadesimal.

http://en.wikipedia.org/wiki/Primitive_wrapper_class


0

karena variabel bool Anda menunjuk ke nol, Anda akan selalu mendapatkan NullPointerException, Anda perlu menginisialisasi variabel terlebih dahulu di suatu tempat dengan nilai bukan nol, dan kemudian memodifikasinya.


1
Jika hanya itu, catchblok akan menangani NullPointerException. Masalahnya di sini adalah bahwa OP mencoba untuk membuka kotak null-referensi ke primitif.
Mike Adler

"Anda akan selalu" - Tidak selalu, kecuali untuk sampel, kode sederhana yang tidak melakukan apa pun di antara menginisialisasi variabel ke nulldan kemudian mengujinya. Kode nyata mungkin tidak sesederhana itu atau seluruh iftes dapat dihapus.
nnnnnn
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.