Boolean vs boolean di Jawa

195

Ada diskusi sekitar Integervs intdi Jawa. Nilai default dari yang pertama adalah nullsementara yang kedua itu 0. Bagaimana dengan Booleanvs boolean?

Variabel dalam aplikasi saya dapat memiliki 0/ 1nilai. Saya ingin menggunakan boolean/ Booleandan memilih untuk tidak menggunakan int. Bisakah saya menggunakan Boolean/ booleansebagai gantinya?

Neel
sumber
2
Untuk alasan desain sistem saya akan memilih Boolean karena memiliki opsi "Pengguna belum memutuskan" yang tidak sama dengan "benar", atau "salah". Saya akan menggunakan boolean primitive hanya dalam kasus jika saya 100% yakin opsi benar / salah sudah cukup. Dalam database, opsi NULL biasanya tersedia tanpa masalah (atau dengan hanya menghapus TIDAK NULL pembatasan pada permintaan nanti)
CsBalazsHungary
2
Duplikat yang tepat dari Apa perbedaan antara boolean dan Boolean di Jawa? (karena GWT tidak membuat perbedaan).
Dan Dascalescu

Jawaban:

270

Ya, Anda bisa menggunakan Boolean/ booleansebagai gantinya.

Yang pertama adalah Obyek dan yang kedua adalah tipe primitif.

  • Yang pertama, Anda akan mendapatkan lebih banyak metode yang akan berguna.

  • Yang kedua murah mengingat biaya memori Yang kedua akan menghemat lebih banyak memori, jadi lakukan saja

Sekarang pilih jalanmu.

Jigar Joshi
sumber
70
Anda bisa mengatakan ini sebagai "yang kedua akan menghemat lebih banyak memori, jadi lakukanlah". Metode yang berguna pada Boolean sebagian besar dapat dipanggil tanpa memiliki instance dari itu.
DJClayworth
3
Selama Anda menggunakan Boolean.valueOf (nilai) Boolean baru (nilai), memori seharusnya tidak menjadi masalah.
Greg Case
2
karena AsyncTask, Anda hanya bisa menggunakan Booleansaja boolean.
Raptor
98
Perlu dicatat bahwa Boolean sebenarnya memiliki 3 status ... true, falsedan di nullmana boolean memiliki 2 status logis ( truedan false)
respectTheCode
14
Boolean adalah trillean :)
Topera
50

Boolean membungkus tipe primitif boolean. Di JDK 5 dan ke atas, Oracle (atau Sun sebelum Oracle membelinya) memperkenalkan autoboxing / unboxing , yang pada dasarnya memungkinkan Anda untuk melakukan ini

boolean result = Boolean.TRUE;

atau

Boolean result = true; 

Yang pada dasarnya adalah kompiler,

Boolean result = Boolean.valueOf(true);

Jadi, untuk jawaban Anda, itu YA.

Buhake Sindi
sumber
4
Catatan: Anda tidak selalu dapat dengan aman memberikan Booleana boolean. Jika Anda Booleanyaitu nulldan Anda mencoba untuk menetapkan ke boolean, itu akan melempar NullPointerExceptionpada saat runtime.
Duncan Luk
jika Booleansuatu kelas lalu mengapa nilainya selalu salah bahkan jika saya mengubah nilai dari kelas lain yang merujuk ke variabel Boolean yang sama? apa gunanya ini Booleanjika kita tidak dapat merujuk dari berbagai instance instance / pass sebagai argumen?
user924
menemukan jawaban, kita dapat menggunakan AtomicBooleandan
merujuknya
35

Saya sedikit memperluas jawaban yang diberikan (karena sejauh ini mereka berkonsentrasi pada terminologi "sendiri" / buatan mereka yang berfokus pada pemrograman bahasa tertentu alih-alih menjaga gambaran yang lebih besar di belakang layar menciptakan bahasa pemrograman , secara umum, yaitu ketika hal-hal seperti pertimbangan keamanan-jenis vs memori membuat perbedaan):

int bukan boolean

Mempertimbangkan

    boolean bar = true;      
    System.out.printf("Bar is %b\n", bar);
    System.out.printf("Bar is %d\n", (bar)?1:0);
    int baz = 1;       
    System.out.printf("Baz is %d\n", baz);
    System.out.printf("Baz is %b\n", baz);

dengan output

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

Kode Java pada baris ke-3 (bar)?1:0menggambarkan bahwa bilah ( boolean ) tidak dapat secara implisit dikonversi (dicor) menjadi int . Saya membahas hal ini bukan untuk menggambarkan detail implementasi di belakang JVM, tetapi untuk menunjukkan bahwa dalam hal pertimbangan tingkat rendah (karena ukuran memori) kita harus lebih memilih nilai daripada keamanan jenis. Terutama jika jenis keamanan itu tidak benar-benar / sepenuhnya digunakan seperti dalam jenis boolean di mana pemeriksaan dilakukan dalam bentuk

jika nilai \ dalam {0,1} kemudian dilemparkan ke tipe boolean, jika tidak lempar pengecualian.

Semua menyatakan bahwa {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Sepertinya berlebihan, kan? Keamanan jenis benar-benar penting dalam tipe yang ditentukan pengguna, bukan dalam casting primitif secara implisit (meskipun yang terakhir termasuk dalam yang pertama).

Bytes bukan tipe atau bit

Perhatikan bahwa dalam memori variabel Anda dari kisaran {0,1} masih akan menempati setidaknya satu byte atau kata (xbits tergantung pada ukuran register) kecuali diurus secara khusus (misalnya dikemas dengan baik dalam memori - 8 "boolean" bit menjadi 1 byte - maju dan mundur).

Dengan lebih memilih keamanan jenis (seperti dalam memasukkan / membungkus nilai ke dalam kotak dari jenis tertentu) daripada pengemasan nilai tambahan (misalnya menggunakan bit shift atau aritmatika), orang tidak secara efektif memilih menulis lebih sedikit kode daripada mendapatkan lebih banyak memori. (Di sisi lain, orang selalu dapat menentukan jenis pengguna khusus yang akan memfasilitasi semua konversi yang tidak bernilai daripada Boolean).

kata kunci vs. jenis

Terakhir, pertanyaan Anda adalah tentang membandingkan kata kunci vs. jenis . Saya percaya penting untuk menjelaskan mengapa atau bagaimana tepatnya Anda akan mendapatkan kinerja dengan menggunakan / lebih suka kata kunci ("ditandai" sebagai primitif ) daripada tipe (kelas komposit yang dapat ditentukan pengguna normal menggunakan kelas kata kunci lain ) atau dengan kata lain

boolean foo = true;

vs.

Boolean foo = true;

"Benda" pertama (tipe) tidak dapat diperpanjang (subklas) dan bukan tanpa alasan. Terminologi Java yang efektif dari kelas-kelas primitif dan pembungkus dapat dengan mudah diterjemahkan ke dalam nilai inline (suatu LITERAL atau sebuah konstanta yang secara langsung diganti oleh kompiler setiap kali dimungkinkan untuk menyimpulkan substitusi atau jika tidak - masih mundur ke dalam pembungkus nilai).

Optimalisasi tercapai karena sepele:

"Lebih sedikit operasi pengecoran runtime => lebih banyak kecepatan."

Itulah sebabnya ketika inferensi tipe aktual dilakukan, ia mungkin (masih) berakhir di instantiating kelas pembungkus dengan semua informasi tipe jika perlu (atau mengubah / casting ke dalamnya).

Jadi, perbedaan antara boolean dan Boolean adalah persis di Kompilasi dan Runtime (agak jauh akan tetapi hampir sama instanceof vs getClass () ).

Akhirnya, autoboxing lebih lambat daripada primitif

Perhatikan fakta bahwa Java dapat melakukan autoboxing hanyalah "gula sintaksis". Itu tidak mempercepat apa pun, hanya memungkinkan Anda untuk menulis lebih sedikit kode. Itu dia. Pengecoran dan pembungkus ke dalam wadah informasi tipe masih dilakukan. Untuk alasan kinerja pilihlah aritmatika yang akan selalu melewatkan perawatan ekstra untuk membuat instance kelas dengan informasi tipe untuk mengimplementasikan keselamatan tipe. Kurangnya keamanan jenis adalah harga yang Anda bayar untuk mendapatkan kinerja. Untuk kode dengan ekspresi tipe keselamatan bernilai boolean (ketika Anda menulis lebih sedikit dan karenanya kode implisit ) akan sangat penting misalnya untuk kontrol aliran if-then-else.

Yauhen Yakimovich
sumber
16

Anda dapat menggunakan konstanta Boolean - Boolean.TRUEdan Boolean.FALSEbukannya 0dan 1. Anda dapat membuat variabel sebagai tipe booleanjika primitif adalah yang Anda cari. Dengan cara ini Anda tidak perlu membuat Booleanobjek baru .

CoolBeans
sumber
3

Pada dasarnya boolean mewakili tipe data primitif di mana Boolean mewakili tipe data referensi. cerita ini dimulai ketika Java ingin menjadi murni berorientasi objek itu disediakan konsep kelas pembungkus untuk datang menggunakan tipe data primitif.

boolean b1;
Boolean b2;

b1dan b2tidak sama.

Sachin Jadhav
sumber
3

Satu pengamatan: (meskipun ini bisa dianggap efek samping)

boolean menjadi primitif dapat mengatakan ya atau tidak.

Boolean adalah objek (bisa merujuk pada ya atau tidak atau 'tidak tahu' yaitu nol)

Sudip Bhandari
sumber
1

Anda bisa menggunakan Boolean / boolean. Kesederhanaan adalah caranya. Jika Anda tidak memerlukan api spesifik (Koleksi, Aliran, dll.) Dan Anda tidak memperkirakan bahwa Anda akan membutuhkannya - gunakan versi primitifnya (boolean).

  1. Dengan primitif Anda menjamin bahwa Anda tidak akan melewati nilai nol.
    Anda tidak akan jatuh dalam perangkap seperti ini. Kode di bawah ini melempar NullPointerException (dari: Booleans, operator kondisional, dan autoboxing ):

    public static void main(String[] args) throws Exception { Boolean b = true ? returnsNull() : false; // NPE on this line. System.out.println(b); } public static Boolean returnsNull() { return null; }

  2. Gunakan Boolean saat Anda membutuhkan objek, misalnya:

    • Aliran Boolean,
    • Pilihan
    • Koleksi Boolean
Witold Kaczurba
sumber