私はとのルールを知っていますが、と&&
は||
何ですか?これらを例を挙げて説明してください。&
|
11 に答える
これらは、ビット単位のAND演算子とビット単位のOR演算子です。
int a = 6; // 110
int b = 4; // 100
// Bitwise AND
int c = a & b;
// 110
// & 100
// -----
// 100
// Bitwise OR
int d = a | b;
// 110
// | 100
// -----
// 110
System.out.println(c); // 4
System.out.println(d); // 6
入力に基づくオペレーターのさまざまな動作に関して、Java言語仕様(15.22.1、15.22.2)の適切なセクションを指摘してくれたCarlosに感謝します。
実際、両方の入力がブール値の場合、演算子はブール論理演算子と見なされ、条件付き-And(&&
)および条件付き-Or(||
)演算子と同様に動作しますが、以下が安全である間は短絡しないという事実があります。 :
if((a != null) && (a.something == 3)){
}
これではありません:
if((a != null) & (a.something == 3)){
}
「短絡」とは、オペレーターが必ずしもすべての状態を検査するわけではないことを意味します。上記の例では、そうでない&&
場合にのみ2番目の条件を調べます(そうでない場合、ステートメント全体がfalseを返し、とにかく次の条件を調べるのは無意味です)。したがって、のステートメントは例外を発生させないか、「安全」と見なされます。 。」a
null
a.something
&
演算子は常に句内のすべての条件を調べるため、上記の例では、が実際には値でa.something
ある場合に評価され、例外が発生する可能性があります。a
null
あなたは両方の演算子の論理的な意味について話していると思います、ここにあなたはテーブルを持っています-履歴書:
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
短絡評価、最小評価、またはマッカーシー評価(John McCarthyの後)は、最初の引数が値を決定するのに十分でない場合にのみ2番目の引数が実行または評価される、一部のプログラミング言語の一部のブール演算子のセマンティクスです。式:AND関数の最初の引数がfalseと評価された場合、全体の値はfalseである必要があります。また、OR関数の最初の引数がtrueと評価された場合、全体の値はtrueである必要があります。
安全ではないということは、演算子が常に句内のすべての条件を調べることを意味します。したがって、上記の例では、xが実際に0の値である場合に、1 / xが評価され、例外が発生します。
ここにはたくさんの答えがあることは知っていますが、それらはすべて少し混乱しているようです。したがって、Java oracle学習ガイドからいくつかの調査を行った後、&&または&をいつ使用するかについて3つの異なるシナリオを考え出しました。3つのシナリオは、論理積、ビット単位のAND、およびブールANDです。
論理積:
論理積(別名条件付きAND)は&&演算子を使用します。これは短絡的な意味です。左側のオペランドがfalseの場合、右側のオペランドは評価されません。
例:
int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"
上記の例では、ifステートメントの最初のオペランドがfalseであるため、xのコンソールに出力される値は0になります。したがって、Javaは計算する必要がなく(1 == ++ x)、xは計算されません。
ビットごとのAND: ビットごとのANDは&演算子を使用します。これは、値に対してビット単位の演算を実行するために使用されます。2進数の演算を見ると、何が起こっているのかを簡単に確認できます。例:
int a = 5; // 5 in binary is 0101
int b = 12; // 12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4
例でわかるように、数値5と12の2進数表現が並んでいる場合、ビット単位のANDを実行すると、両方の数値の同じ桁が1である2進数のみが生成されます。したがって、0101&1100 == 0100. 10進数で5&12==4です。
ブールAND: ブールAND演算子は、ビット単位のANDと論理ANDの両方と同様に異なる動作をします。私はそれを2つのブール値(またはビット)間でビット単位のANDを実行するものと考えるのが好きなので、&演算子を使用します。ブール値は、論理式の結果でもあります。
論理積とよく似ていますが、論理積とは異なり、真または偽の値を返しますが、短絡はありません。その理由は、ビット単位のANDを実行するには、左オペランドと右オペランドの両方の値を認識している必要があるためです。これが例です:
int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"
これで、ifステートメントが実行されると、左のオペランドがfalseであっても、式(1 == ++ x)が実行されます。したがって、xに対して出力される値は、増分されるため1になります。
これは、論理OR(||)、ビットごとのOR(|)、およびブールOR(|)にも当てはまります。これにより、混乱が解消されることを願っています。
演算子&&および|| は短絡しています。つまり、左側の式の値が結果を決定するのに十分である場合、右側の式を評価しません。
&と| &&および||と同じ結果を提供します 演算子。違いは、それらが常に式の両側を評価することです。ここで、&&と|| 最初の条件が結果を決定するのに十分であるかどうかの評価を停止します。
Javaでは、単一の演算子&、|、^ 、! オペランドに依存します。両方のオペランドがintの場合、ビット演算が実行されます。両方がブール値の場合、「論理」演算が実行されます。
両方のオペランドが一致しない場合、コンパイル時エラーがスローされます。
二重演算子&&、|| 単一の対応するものと同様に動作しますが、両方のオペランドは条件式である必要があります。次に例を示します。
if((a <0)&&(b <0)){...}または同様に、if((a <0)||(b <0)){...}
ソース:javaプログラミング言語第4版
&
整数型の|
ビット演算子です(例int
):http ://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
ブール値のみで||
動作します(他の回答がすでに述べているように、短絡します)。
ビット単位のAND演算子とビット単位のOR演算子は、同じ式で使用される条件付きANDと条件付きORの前に常に評価されることを知っておくと便利な場合があります。
if ( (1>2) && (2>1) | true) // false!
&&; || 論理演算子です....短絡
&; | ブール論理演算子です....非短絡
式の実行の違いに移ります。ビット演算子は、左側の結果に関係なく、両側を評価します。ただし、論理演算子を使用して式を評価する場合、右側の式の評価は左側の条件に依存します。
例えば:
int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
これにより、i=26が出力されます。j = 25、最初の条件が偽であるため、右側の条件に関係なく、結果はとにかく偽であるため、右側の条件はバイパスされます。(短絡)
int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);
ただし、これはi=26を出力します。j = 26、
ブール&演算子を含む式が評価される場合、両方のオペランドが評価されます。次に、&演算子がオペランドに適用されます。
&&演算子を含む式が評価されると、最初のオペランドが評価されます。最初のオペランドがfalseと評価された場合、2番目のオペランドの評価はスキップされます。
最初のオペランドがtrueの値を返す場合、2番目のオペランドが評価されます。2番目のオペランドがtrueの値を返す場合、&&演算子が1番目と2番目のオペランドに適用されます。
|に似ています および||。
基本的な違いは、&
主にでビット単位の演算に使用されることlong
、int
またはbyte
一種のマスクに使用できることですが、論理の代わりに使用しても結果が異なる場合があります&&
。
いくつかのシナリオでは、違いがより顕著になります。
- 一部の式の評価には時間がかかります
- 式の1つを評価できるのは、前の式が真である場合のみです。
- 式にはいくつかの副作用があります(意図されているかどうかは関係ありません)
最初のポイントは非常に単純で、バグは発生しませんが、時間がかかります。1つの条件ステートメントに複数の異なるチェックがある場合は、より安価であるか、失敗する可能性が高いものを左側に配置します。
2番目のポイントについては、次の例を参照してください。
if ((a != null) & (a.isEmpty()))
null
2番目の式を評価すると。が生成されるため、これは失敗しますNullPointerException
。論理演算子&&
は怠惰です。左のオペランドがfalseの場合、右のオペランドが何であっても結果はfalseになります。
3番目のポイントの例-トリガーやカスケードなしでDBを使用するアプリがあるとします。Buildingオブジェクトを削除する前に、Departmentオブジェクトの建物を別の建物に変更する必要があります。また、操作ステータスがブール値(true =成功)として返されるとしましょう。それで:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
これにより、両方の式が評価され、何らかの理由で部門の更新が失敗した場合でも、建物の削除が実行されます。を使用&&
すると、意図したとおりに機能し、最初の障害後に停止します。
についてa || b
は、と同等であり、trueの!(!a && !b)
場合a
は停止し、これ以上の説明は不要です。