4

重複の可能性:
& と && の違い

Javaでの短絡操作に関するいくつかのチュートリアルと回答を読みましたが、Javaが二重垂直パイプと二重アンパサンドの短絡を処理する方法の違いをまだよく理解していません。例えば ​​...

論理 AND 短絡評価が失敗するのはなぜですか?

JSL 15.23 を引用します。条件付き And 演算子 &&

The conditional-and operator && is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.

public static void main( String... args ) {


    int a = 1;

    int b = 2;

    // Okay. Prints
    if( a == 1 | b == 3 ) {

        System.out.println( "Comparison via |" + "\na is " + a + "\nb is " + b );

    }

    // Okay. Prints
    if( a == 1 || b == 3 ) {

        System.out.println( "Comparison via ||" + "\na is " + a + "\nb is " + b );

    }

    // Okay. Does not print
    if( a == 1 & b == 3 ) {

        System.out.println( "Comparison via &" + "\na is " + a + "\nb is " + b );

    }

    // I don't understand. Shouldn't the Short Circuit succeed since the left side of the equation equals 1?
    if( a == 1 && b == 3 ) {

        System.out.println( "Comparison via &&" + "\na is " + a + "\nb is " + b );

    }

}
4

5 に答える 5

12

理解できない。式の左辺が 1 に等しいので、短絡は成功するはずではありませんか?

いいえ、絶対に違います。ポイントは左右のオペランドが;の場合に&&のみ結果が得られることです。短絡は、左のオペランドが の場合、右のオペランドが評価されないことを意味します。これは、その時点で答えがわかっているためです。truetruefalse

詳細については、JLS のセクション15.23および15.24をお読みください。

条件付き AND 演算子 && は & (§15.22.2) に似ていますが、左側のオペランドの値が true の場合にのみ右側のオペランドを評価します。

条件付き OR 演算子 || 演算子は | のようなものです (§15.22.2)、ただし、左側のオペランドの値が false の場合にのみ右側のオペランドを評価します。

于 2012-11-16T23:40:04.030 に答える
2

booleansと共に使用する場合、ビット単位の演算子 (|および&) は論理演算子 (および) と同様ですが、次の点が異なります。||&&

  • &&場合、最初の引数がの場合、式全体がfalseである必要があるため、2 番目の引数は評価されません。の場合、両方の引数が関係なく評価されます。false&

  • ||場合、最初の引数がの場合、式全体がtrueである必要があるため、2 番目の引数は評価されません。の場合、両方の引数が関係なく評価されます。true|

これが「ショートサーキット」の意味です: 場合によっては、最初の引数の値だけで式全体の値を知ることができるため、2 番目の引数を評価しないままにするプロセスです。


falseここで、次の式が:である理由を尋ねますa == 1 && b == 3。まあ、短絡はそれとは何の関係もありません。a = 1そして、そうではないb = 2ので、ステートメントは明らかにそうです。"a is 1 and b is 2falseb2

于 2012-11-16T23:40:59.807 に答える
1

最初のオペランドを評価した後に結果が決定される場合、論理演算子||&&ショートサーキット。||これは、最初のオペランドが に評価される場合true、 forに&&評価される場合に当てはまりfalseます。

の最初のオペランドが で||ある場合でも、2 番目のオペランドが である場合のfalse全体的な結果を得ることができます。同様に、 の最初のオペランドが である場合でも、2 番目のオペランドが である場合に評価できます。truetrue&&truefalsefalse

Java では、演算子|および&は、ビットごとの演算子 (整数引数に適用された場合) であるだけでなく、最初の値に関係なく両方のオペランドを評価する非短絡論理演算子でもあります。

于 2012-11-16T23:39:36.847 に答える
1

& と && の両方が真である必要があるため、コードは期待どおりに動作しています。

唯一の違いは、& は両側を実行しますが、&& は最初の側のみを実行するということです。これは、右側が最終結果と無関係になるためです。

この効果は、次のようなコードにとって重要です。

if (obj == null || obj.isSomthing())

| を使用すると NPE がスローされます。obj は null でした。

于 2012-11-16T23:40:03.147 に答える
0
if( a == 1 && b == 3 ) {
   System.out.println( "Comparison via &&" + "\na is " + a + "\nb is " + b );
}

最初に、a == 1これが真であるかどうかをチェックするので、続けてチェックする必要があります。b == 3これは真ではないため、出力が得られません。true && falsefalse

もしあなたが持っていたら

if( b == 3 && a == 1 ) {
       System.out.println( "Comparison via &&" + "\na is " + a + "\nb is " + b );
}

それは最初にチェックします。そうではないので、 is alwaysであるため、何b == 3であっても、気にする必要はありません。a == 1false && whateverfalsewhatever

それはあなたの質問に答えていますか?

于 2012-11-16T23:39:49.280 に答える