どのセットが短絡しており、複雑な条件式が短絡しているとはどういう意味ですか?
public static void main(String[] args) {
int x, y, z;
x = 10;
y = 20;
z = 30;
// T T
// T F
// F T
// F F
//SET A
boolean a = (x < z) && (x == x);
boolean b = (x < z) && (x == z);
boolean c = (x == z) && (x < z);
boolean d = (x == z) && (x > z);
//SET B
boolean aa = (x < z) & (x == x);
boolean bb = (x < z) & (x == z);
boolean cc = (x == z) & (x < z);
boolean dd = (x == z) & (x > z);
}
&&
および||
演算子は「短絡」します。つまり、必要でない場合は右側を評価しません。
&
および|
演算子は、論理演算子として使用される場合、常に両側を評価します。
演算子ごとに短絡のケースは1つだけあり、それらは次のとおりです。
false && ...
-右側が何であるかを知る必要はありません。結果はfalse
でなければなりませんtrue || ...
-右側が何であるかを知る必要はありません。結果はtrue
でなければなりません簡単な例で動作を比較しましょう:
public boolean longerThan(String input, int length) {
return input != null && input.length() > length;
}
public boolean longerThan(String input, int length) {
return input != null & input.length() > length;
}
2番目のバージョンは非短絡演算子&
を使用し、NullPointerException
がinput
の場合はnull
をスローしますが、1番目のバージョンはfalse
を返します。例外;
SET Aは、短絡ブール演算子を使用します。
ブール演算子のコンテキストで「短絡」とは、一連のブールb1、b2、...、bnの場合、これらのブールの最初の値が真になると、短絡バージョンが評価を停止することです(|| )またはfalse(&&)。
例えば:
// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)
// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)
簡単に言えば、short-circuitingは、答えがもはや変わらないことがわかったら評価を停止することを意味します。たとえば、論理AND
sのチェーンを評価していて、そのチェーンの途中でFALSE
を発見した場合、その値はどうであれ、結果がfalseになることがわかります。チェーン内の残りの式。 OR
sのチェーンについても同様です。TRUE
を発見すると、すぐに答えがわかるので、残りの式の評価をスキップできます。
Javaに対して、&&
の代わりに&
および||
の代わりに|
を使用して、ショートサーキットが必要であることを示します。投稿の最初のセットは短絡です。
これは、いくつかのCPUサイクルを節約する試み以上のものであることに注意してください。このような式では
if (mystring != null && mystring.indexOf('+') > 0) {
...
}
短絡とは、正しい動作とクラッシュの違いを意味します(mystringがnullの場合)。
boolean a = (x < z) && (x == x);
この種類は短絡します。つまり、(x < z)
がfalseと評価された場合、後者は評価されず、a
はfalseになります。そうでない場合、&&
も(x == x)
を評価します。
&
はビットごとの演算子ですが、短絡しないブール型AND演算子でもあります。
次のような方法でテストできます(それぞれの場合にメソッドが呼び出される回数を参照してください)。
public static boolean getFalse() {
System.out.println("Method");
return false;
}
public static void main(String[] args) {
if(getFalse() && getFalse()) { }
System.out.println("=============================");
if(getFalse() & getFalse()) { }
}
短絡とは、最初のオペレーターが最終結果を決定した場合、2番目のオペレーターがチェックされないことを意味します。
例えば。式は次のとおりです:True ||偽
||の場合、必要なのはsideの1つがTrueになることです。したがって、左側が真である場合、右側をチェックしても意味がありません。したがって、それはまったくチェックされません。
同様に、False && True
&&の場合、both sidesがTrueである必要があります。したがって、左側がFalseの場合、右側をチェックしても意味がありません。答えはFalseでなければなりません。したがって、それはまったくチェックされません。
Javaは、他のほとんどのコンピューター言語にはない2つの興味深いブール演算子を提供します。 ANDおよびORのこれらの2次バージョンは、短絡論理演算子として知られています。前の表からわかるように、Aがtrueの場合、Bが何であっても、OR演算子はtrueになります。
同様に、Bが何であっても、Aが偽の場合、AND演算子は偽になります。これらの演算子の||
および&&
形式ではなく、|
および&
形式を使用する場合、Javaは適切な評価を行いません-handオペランドのみ。これは、右側のオペランドが適切に機能するために、左側のオペランドがtrueまたはfalseであることに依存している場合に非常に便利です。
たとえば、次のコードフラグメントは、短絡論理評価を利用して、除算演算が評価される前に有効であることを確認する方法を示しています。
if ( denom != 0 && num / denom >10)
AND(&&
)の短絡形式が使用されているため、ゼロで除算することでランタイム例外が発生するリスクはありません。このコード行が単一の&
バージョンのANDを使用して記述されている場合、両側を評価する必要があり、denom
がゼロの場合にランタイム例外が発生します。
ブールロジックが関係する場合は、ANDおよびORの短絡形式を使用し、単一文字バージョンをビット単位操作専用に残すのが標準的な方法です。ただし、このルールには例外があります。たとえば、次のステートメントを考えてみましょう。
if ( c==1 & e++ < 100 ) d = 100;
ここで、単一の&
を使用すると、e
が1に等しいかどうかにかかわらず、c
にインクリメント操作が適用されます。
&
演算子と&&
演算子にはいくつかの違いがあります。 |
と||
にも同じ違いが適用されます。覚えておくべき最も重要なことは、&&
はブール演算対象にのみ適用される論理演算子であり、&
はビットごと演算子であることです。これは、ブール型だけでなく整数型にも適用されます。
論理演算を使用すると、特定の場合(&&
の第1オペランドがfalse
である、または||
の第1オペランドがtrue
であるなど)式の残りを評価する必要はありません。これは、フィールドまたはメソッドにアクセスする前にnull
をチェックしたり、除算する前に潜在的なゼロをチェックしたりする場合などに非常に役立ちます。複雑な式の場合、式の各部分は同じ方法で再帰的に評価されます。たとえば、次の場合:
(7 == 8) || ((1 == 3) &&(4 == 4))
強調された部分のみが評価されます。 ||
を計算するには、最初に7 == 8
がtrue
であるかどうかを確認します。その場合、右側は完全にスキップされます。右側では、1 == 3
がfalse
であるかどうかのみがチェックされます。そのため、4 == 4
をチェックする必要はなく、式全体がfalse
に評価されます。左側がtrue
の場合、たとえば7 == 7
の代わりに7 == 8
を使用すると、||
式全体がtrue
であるため、右側全体がスキップされます。
ビット演算では、実際にはビットを結合しているだけなので、すべてのオペランドを評価する必要があります。ブール値は実質的にJavaの1ビット整数であり(内部の動作方法に関係なく)、その特別なケースでビット演算子の短絡を行うことができるのは偶然です。一般的な整数&
または|
操作を短絡できない理由は、いずれかのオペランドで一部のビットがオンになり、一部のビットがオフになる可能性があるためです。 1 & 2
のようなものはゼロを生成しますが、両方のオペランドを評価しないとそれを知る方法がありません。
Logical OR:-は、オペランドの少なくとも1つがtrueと評価された場合にtrueを返します。両方のオペランドは、OR演算子を適用する前に評価されます。
Short Circuit OR:-左側のオペランドがtrueを返す場合、右側のオペランドを評価せずにtrueを返します。
if(demon!=0&& num/demon>10)
AND(&&)の短絡形式が使用されているため、demonがゼロのときに実行時例外が発生するリスクはありません。
参照Java 2 Herbert Schildtによる第5版