Pengaruh Operator Bitwise pada Boolean di Java

118

Operator bitwise seharusnya melakukan perjalanan variabel dan mengoperasikannya sedikit demi sedikit. Dalam kasus integer, longs, chars ini masuk akal. Variabel ini dapat berisi berbagai nilai yang dipaksakan oleh ukurannya.

Dalam kasus boolean, bagaimanapun, boolean hanya dapat berisi dua nilai. 1 = benar atau 0 = salah. Tetapi ukuran boolean tidak ditentukan. Ini bisa sebesar byte atau sekecil bit.

Jadi, apa efek menggunakan operator bitwise pada boolean? Apakah JVM pada dasarnya menerjemahkannya ke operator logika normal dan melanjutkan? Apakah itu memperlakukan boolean sebagai entitas bit tunggal untuk tujuan operasi? Ataukah hasilnya tidak terdefinisi bersama dengan ukuran boolean?

Daniel Bingham
sumber
1
Saya pikir Anda tidak dapat menggunakan operator bitwise pada boolean. Hanya pada angka. Saya yakin ~ tidak akan berfungsi, saya tidak tahu bagaimana dengan operator lain.
Martijn Courteaux
4
Anda dapat menggunakan beberapa di antaranya, kami baru saja menemukan | digunakan dalam kode lama kami. Kami menghapusnya, tetapi kode ini dikompilasi dan berfungsi.
Daniel Bingham
9
Karena yang satu mengalami korsleting dan yang lainnya tidak (lihat jawaban mobrule), sebelum Anda mengubah | ke || Anda mungkin ingin memastikan ekspresi boolean berikutnya tidak memiliki efek samping yang ingin selalu dijalankan oleh programmer asli.
John M Gant

Jawaban:

122

Operator &,, ^dan |adalah operator bitwise ketika operan adalah tipe integral primitif. Mereka adalah operator logika ketika operannya adalah boolean, dan perilakunya dalam kasus terakhir ditentukan. Lihat bagian 15.22.2 dari Spesifikasi Bahasa Java untuk detailnya.

Noel Ang
sumber
57
Secara khusus, & dan ^ dan | adalah operator boolean logika non-short-circuit.
Ken
14
Berikut tautan langsung ke bagian yang disebutkan di atas: docs.oracle.com/javase/specs/jls/se7/html/…
Andy Thomas
Jika hal di atas benar, mengapa ideone.com/oGSF7c mengeluarkan pengecualian pointer nol? Jika |=operatornya logis, program seharusnya tidak menjalankan x.getValue()direktif.
ikromm
1
@JohnKrommidas, x Anda nol, itulah sebabnya Anda mendapatkan NullPointerException. Anda perlu membuatnya.
Ben
4
@Ben, Seperti yang dikatakan @Ken, logikanya non-short-circuiting, jadi bagian kedua dievaluasi. Jadi a || x.foo()aman jika x adalah nol, tetapi a | x.foo()tidak. |=mengikuti aturan yang sama seperti |.
Michael Smith
86

Menggunakan operator bitwise dapat menghindari perilaku hubungan pendek:

boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();

Jika booleanExpression1()mengevaluasi ke false, maka
booleanExpression2()tidak dievaluasi dalam kasus pertama, dan
booleanExpression2()(dan apa pun efek samping mungkin memiliki) yang dievaluasi dalam kasus kedua,

massa
sumber
2
Dan operasi bitwise biasanya bekerja lebih cepat daripada operasi sirkuit pendek (asalkan evaluasinya sederhana)
rds
1
Bitwise &akan lebih cepat, tetapi panggilan ke fungsi kedua dapat diabaikan dengan penggunaan&&
NatNgs
20

Di luar apa yang tercakup dalam jawaban lain, perlu dicatat &&dan ||memiliki prioritas yang berbeda dari &dan |.

Ekstrak dari tabel prioritas (dengan prioritas tertinggi di atas).

bitwise AND                 &
bitwise exclusive OR        ^
bitwise inclusive OR        |
logical AND                 &&
logical OR                  ||

Apa artinya ini bagi Anda?

Sama sekali tidak ada, selama Anda tetap berpegang pada hanya &dan |atau hanya &&dan ||.

Namun, karena |memiliki prioritas lebih tinggi daripada &&(sebagai lawan ||, yang memiliki prioritas lebih rendah), mencampurnya secara bebas dapat menyebabkan perilaku yang tidak terduga.

Begitu a && b | c && dpula dengan a && (b | c) && d,
berlawanan dengan a && b || c && dyang akan terjadi (a && b) || (c && d).

Untuk membuktikan bahwa mereka tidak sama, pertimbangkan kutipan dari tabel kebenaran:

a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d)
F | T | T | T |   T   |   F    |    T   |         F       |        T
                                                  ^                ^
                                                  |- not the same -|

Jika Anda ingin OR memiliki prioritas yang lebih tinggi daripada AND, Anda dapat menggunakan |dan&& bersama sama, tetapi ini tidak disarankan.

Tetapi Anda benar-benar harus meletakkannya dalam tanda kurung untuk memperjelas prioritas setiap kali menggunakan simbol yang berbeda, yaitu (a && b) || c(tanda kurung untuk memperjelas prioritas), a && b && c(tidak perlu tanda kurung).

Bernhard Barker
sumber
3

Bahkan jika itu akan berhasil, Anda tidak boleh melakukannya. Spesifikasi bahasa menentukan operator bitwise hanya jika kedua operan berjenis integer primitif atau keduanya berjenis boolean. Saya akan mengatakan untuk kasus lain, hasilnya tidak ditentukan:

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228

LeffeBrune
sumber
Pertanyaannya adalah tentang boolean, bukan tentang primitif atau campuran antara primitif dan boolean.
talonx