Javaのブール値に対するビット演算子の影響


118

ビット演算子は変数を移動し、それらを少しずつ操作することになっています。integers、longs、charsの場合、これは理にかなっています。これらの変数には、サイズによって適用される値の全範囲を含めることができます。

ただし、ブール値の場合、ブール値には2つの値しか含めることができません。1 = trueまたは0 = false。ただし、ブール値のサイズは定義されていません。1バイト程度の大きさでも、少し小さいものでもかまいません。

では、ブール値に対してビットごとの演算子を使用する効果は何ですか?JVMは本質的に、JVMを通常の論理演算子に変換して先に進みますか?演算の目的でブール値を単一ビットエンティティとして扱いますか?または、ブール値と一緒に結果が定義されていませんか?


1
ブール値ではビット演算子を使用できないと思います。数字のみ。〜は機能しません。他の演算子についてはわかりません。
Martijn Courteaux、2009年

4
それらのいくつかを使用できます。従来のコードで使用されていました。削除していますが、このコードはコンパイルされて機能しました。
ダニエルビンガム、

9
|を変更する前に、1つは短絡しており、もう1つは短絡していない(mob​​ruleの回答を参照)。へ|| 後続のブール式に、元のプログラマが常に実行することを意図した副作用がないことを確認したい場合があります。
ジョンMガント

回答:


122

事業者は&^、および|オペランドがプリミティブ整数型であるビット演算子です。オペランドがブールの場合は論理演算子であり、後者の場合の動作が指定されています。詳細については、Java言語仕様のセクション15.22.2を参照してください。


56
具体的には、&および^および| 非短絡論理ブール演算子です。
Ken

14
上記のセクションへの直接リンクは次のとおりです。docs.oracle.com
Andy Thomas

上記に該当する場合、ideone.com / oGSF7cがnullポインター例外をスローするのはなぜですか?場合は|=、オペレータが論理的だった、プログラムが実行したことはなかったはずですx.getValue()ディレクティブを。
ikromm、2015

1
@ JohnKrommidas、xがnullであるため、NullPointerExceptionが発生します。それをインスタンス化する必要があります。
Ben

4
@ Ben、@ Kenが言うように、ロジックは非短絡であるため、2番目の部分が評価されます。したがってa || x.foo()、xがnullであれば安全ですが、そうではa | x.foo()ありません。|=と同じルールに従います|
マイケルスミス

86

ビット演算子を使用すると、短絡動作を回避できます。

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

場合booleanExpression1()評価さをしfalse、その後、
booleanExpression2()最初のケースで評価されず、
booleanExpression2()(それが有することができるどのような副作用)されている第二のケースで評価、


2
また、ビット単位の演算は通常、短絡演算よりも高速に実行されます(評価が単純な場合)
rds

1
ビット単位の&方が高速ですが、2番目の関数の呼び出しは次の使用により無視できます&&
NatNgs

20

他の回答でカバーされているものを超えて、それの価値があることを指摘&&し、||異なる優先度を持っている&し、|

優先順位表から抽出します優先順位が最も高い)。

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

これはどういう意味ですか?

絶対に何もありません。ただし、唯一の&|または唯一の&&、およびのみに固執する限り||

ただし、(|優先順位が低いとは&&対照的に||)よりも優先順位が高いため、それらを自由に混合すると予期しない動作が発生する可能性があります。

だから、a && b | c && d同じであるa && (b | c) && d
とは対照的に、a && b || c && dされるであろう(a && b) || (c && d)

それらが同じではないことを証明するために、真理値表からの抜粋を考えてみましょう:

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

ORをANDよりも優先したい場合は、 |andと&&一緒に使用できますが、これはお勧めできません。

しかし、あなたは本当に異なるシンボル、すなわち使用したときに優先度を明確にするために、括弧内にそれらを置くべきである(a && b) || c(優先順位を明確にするために括弧を)、 a && b && c(ないブラケットは必要ありません)。


3

それがうまくいくとしても、あなたはそれをすべきではありません。言語仕様では、両方のオペランドがプリミティブ整数型であるか、両方がブール型である場合にのみビット演算子を定義します。他の場合については、結果は定義されていません:

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


問題ブールについてであり、プリミティブやプリミティブとブールの混合についてではありません。
talonx 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.