Java'da Bitsel Operatörün Boolean Üzerindeki Etkisi


118

Bitsel operatörlerin değişkenleri gezmesi ve bunlar üzerinde parça parça işlem yapması beklenir. Tam sayılar, uzunlar, karakterler söz konusu olduğunda bu mantıklıdır. Bu değişkenler, boyutları tarafından zorunlu kılınan tüm değerleri içerebilir.

Boolean söz konusu olduğunda ise, boole yalnızca iki değer içerebilir. 1 = doğru veya 0 = yanlış. Ancak boole değerinin boyutu tanımlanmamıştır. Bir bayt kadar büyük veya biraz küçük olabilir.

Öyleyse bitsel bir operatör kullanmanın boole üzerindeki etkisi nedir? JVM, esasen bunu normal bir mantıksal operatöre çevirip devam ediyor mu? İşlemin amacı doğrultusunda boole'yi tek bitlik bir varlık olarak ele alıyor mu? Yoksa sonuç boole boyutuyla birlikte tanımsız mıdır?


1
Bir boolean üzerinde bitsel bir operatör kullanamayacağınızı düşünüyorum. Sadece rakamlarla. Eminim ~ işe yaramayacak, diğer operatörler hakkında ne olduğunu bilmiyorum.
Martijn Courteaux

4
Bunlardan bazılarını kullanabilirsiniz, biz şimdi bir | eski kodumuzda kullanılır. Kaldırıyoruz, ancak bu kod derlendi ve çalıştı.
Daniel Bingham

9
Biri kısa devre yaptığından ve diğeri olmadığından (mobrule'un cevabına bakın), | için || sonraki mantıksal ifadelerin, orijinal programcının her zaman yürütmeyi amaçladığı yan etkilere sahip olmadığından emin olmak isteyebilirsiniz.
John M Gant

Yanıtlar:


122

Operatörler &, ^ve |işlenenler ilkel integral türleri olduğunda bitsel operatörlerdir. İşlenenler boole olduğunda mantıksal operatörlerdir ve ikinci durumdaki davranışları belirtilir. Ayrıntılar için Java Dil Belirtimi'nin 15.22.2 bölümüne bakın .


57
Özellikle, & ve ^ ve | kısa devre olmayan mantıksal boole operatörleri.
Ken

14
İşte yukarıda bahsedilen bölüme doğrudan bir bağlantı: docs.oracle.com/javase/specs/jls/se7/html/…
Andy Thomas

Yukarıdakiler doğruysa, ideone.com/oGSF7c neden boş bir işaretçi istisnası atıyor? Eğer |=operatör mantıklı, program çalıştırmak vermemelilerdi x.getValue()direktifini.
ikromm

1
@JohnKrommidas, x'iniz boş, bu yüzden bir NullPointerException alıyorsunuz. Bunu somutlaştırmanız gerekiyor.
Ben

4
@Ben, @Ken'in dediği gibi mantık kısa devre yapmıyor yani ikinci kısım değerlendiriliyor. Yani a || x.foo()x null ise güvenlidir, ancak a | x.foo()değildir. |=ile aynı kuralları takip eder |.
Michael Smith

86

Bitsel operatörün kullanılması, kısa devre davranışını engelleyebilir:

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

Eğer booleanExpression1()değerlendirir için false, daha sonra
booleanExpression2(), ilk durumda, ve değerlendirilmez
booleanExpression2()(ve her türlü yan etkiler bu olabilir) olan ikinci durumda değerlendirilir


2
Ve bitsel işlem genellikle kısa devreden daha hızlı gerçekleşir (değerlendirmenin basit olması koşuluyla)
2013

1
Bitsel &daha hızlı olacaktır, ancak ikinci işleve yapılan çağrı&&
NatNgs

20

Diğer yanıtlar kaplı ne ötesinde, 's değerinde belirterek &&ve ||farklı önceliğe sahiptir &ve |.

Öncelik tablosundan çıkarın (en yüksek öncelik en üsttedir).

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

Bu senin için ne ifade ediyor?

Kesinlikle hiçbir şey, sürece ya sadece sopa olarak &ve |ya sadece &&ve ||.

Ancak, ( daha düşük önceliğe sahip |olanın &&aksine ||) daha yüksek önceliğe sahip olduğundan , bunları serbestçe karıştırmak beklenmedik davranışlara yol açabilir.

Yani a && b | c && daynıdır a && (b | c) && d,
aksine a && b || c && dolacağını (a && b) || (c && d).

Bunların aynı olmadığını kanıtlamak için doğruluk tablosundan bir alıntı düşünün:

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

VEYA'nın VE'den daha yüksek önceliğe sahip olmasını istiyorsanız ,| ve &&birlikte kullanabilirsiniz , ancak bu önerilmez.

Ancak, farklı semboller kullanırken önceliği netleştirmek için onları gerçekten parantez içine koymalısınız, yani (a && b) || c(önceliği açıklığa kavuşturmak için parantezler), a && b && c(parantez gerekmez).


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.