4

可能的重复:
& 和 && 的差异

我已经阅读了几个关于 java 中短路操作的教程和答案,但我仍然不太了解 java 如何处理双垂直管道与双 & 符号的短路的区别。例如 ...

为什么逻辑与短路评估失败?

引用 JSL 15.23。条件与运算符 &&

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,短路不应该成功吗?

不,绝对不是。的要点&&是,结果只有true当左操作数右操作数是true; 短路意味着如果左操作数是 ,则不对右操作数进行评估false,因为此时答案是已知的。

您应该阅读JLS 的第15.2315.24节以了解更多详细信息:

条件与运算符 && 类似于 &(第 15.22.2 节),但仅当其左侧操作数的值为真时才计算其右侧操作数。

条件或运算符 || 运算符就像 | (§15.22.2),但仅当其左侧操作数的值为假时才评估其右侧操作数。

于 2012-11-16T23:40:04.030 回答
2

booleans 一起使用时,位运算符 ( |and &)与逻辑运算符 ( and )类似,除了:||&&

  • 在 的情况下&&,如果第一个参数是false第二个,则不计算第二个参数,因为整个表达式必须是false。对于&,无论如何都会评估两个参数。

  • 在 的情况下||,如果第一个参数是true第二个,则不计算第二个参数,因为整个表达式必须是true。对于|,无论如何都会评估两个参数。

这就是我们所说的“短路”:不计算第二个参数的过程,因为在某些情况下,我们可以仅从第一个参数的值知道整个表达式的值。


现在你问为什么下面的表达式是false: a == 1 && b == 3。好吧,短路与它无关。a = 1并且b = 2,所以声明显然是,因为不是。"a is 1 and b is 2falseb2

于 2012-11-16T23:40:59.807 回答
1

如果在评估第一个操作数后确定结果,则逻辑运算符||&&短路。对于||这种情况,如果第一个操作数的计算结果为true,对于&&,如果计算结果为false

如果是的第一个操作数||false它仍然可以产生true如果第二个操作数是的整体结果true。类似地,如果第一个操作数&&true,它仍然可以评估为false如果第二个操作数是false

在 Java 中,运算符|&不仅是位运算符(当应用于整数参数时),而且是非短路逻辑运算符,它计算两个操作数而不管第一个值是什么。

于 2012-11-16T23:39:36.847 回答
1

& 和 && 都要求双方都为真,因此代码的行为符合预期。

唯一的区别是 & 执行两边,但 && 如果它是假的,则只执行第一个,因为右侧与最终结果无关。

这样做的效果对于像这样的代码很重要

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

如果您使用 | 会抛出 NPE 并且 obj 为空。

于 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 );
}

它会首先检查是否b == 3并且因为不是这种情况,所以甚至不用费心去看,a == 1因为false && whatever总是false,不管是什么whatever

这是否回答你的问题?

于 2012-11-16T23:39:49.280 回答