Java逻辑“AND”与“OR”短路一致性

时间:2012-11-16 23:37:00

标签: java evaluation logical-operators

  

可能重复:
  Difference in & and &&

我已经阅读了几篇有关java中短路操作的教程和答案,我仍然不太了解java处理双垂直管与双安培的短路的区别。例如......

  

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

引用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 );

    }

}

5 个答案:

答案 0 :(得分:11)

  

我不明白。短路不应该成功,因为等式的左边等于1?

不,绝对没有。 &&的要点是,如果左侧右侧操作数为true,则结果仅为true;短路意味着如果左操作数为false,则不评估右操作数,因为答案在该点已知。

您应该阅读JLS的15.2315.24部分了解更多详情:

  

条件和操作员&&就像& (§15.22.2),但仅在其左侧操作数的值为真时才计算其右侧操作数。

     

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

答案 1 :(得分:2)

boolean一起使用时,按位运算符(|&)与逻辑运算符(||和{的类似 {1}})除了:

  • 对于&&,如果第一个参数为&&,则第二个参数未被评估,因为整个表达式必须为{{1} }。对于false,无论如何都会评估这两个参数。

  • 对于false,如果第一个参数为&,则第二个参数未被评估,因为整个表达式必须为{{1} }。对于||,无论如何都会评估这两个参数。

这就是我们所说的“短路”:离开第二个参数的过程没有评估,因为在某些情况下,我们只能从第一个的值知道整个表达式的值参数。


现在您问为什么以下表达式为true true 。那么,短路与它无关; |false,所以语句a == 1 && b == 3显然是a = 1,因为b = 2不是"a is 1 and b is 2

答案 2 :(得分:1)

如果在评估第一个操作数后确定结果,则逻辑运算符||&&会短路。对于||,如果第一个操作数评估为true,则为&&,如果评估为false,则为<{1}}。

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

在Java中,运算符|&不仅是按位运算符(当应用于整数参数时),而且还是非短路逻辑运算符,它们评估两个操作数,而不管其值是多少第一个。

答案 3 :(得分:1)

两者兼有和&amp;&amp;要求双方都是真的,所以代码的行为符合预期。

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

这对于像

这样的代码很重要
if (obj == null || obj.isSomthing())
如果您使用了|,那么

会抛出一个NPE和obj是空的。

答案 4 :(得分:0)

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

首先检查一下,如果a == 1这是真的,那么必须继续检查b == 3是否为true && false,这不是真的,所以falseif( b == 3 && a == 1 ) { System.out.println( "Comparison via &&" + "\na is " + a + "\nb is " + b ); } 并且你没有得到输出。

如果你有

b == 3

首先会检查是否a == 1并且因为情况并非如此,所以甚至不必费心false && whatever,因为false总是whatever,而不是{{1}} {{1}} 1}}是。

这会回答你的问题吗?