2012-11-16 34 views
4

可能重复:
Difference in & and &&Java的逻辑“与” VS“或”短路一致性

我读过一些教程,并回答关于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); 

    } 

} 
+3

'|'和'&'是按位或/和运算符;它们不同于'||'和'&&',它们是逻辑或/和运算符。 – NullUserException

+0

我知道我没有得到第四名,但是......我迷失在那里:-) –

+0

@NullUserException:他们在短路方面有所不同 - 但JLS在另一方面定义了一个。 ..看到我的答案。 (注意对于'boolean'操作数,它们仍然是逻辑运算符...) –

回答

10

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

不,绝对不是。 &&这一点就是结果只有true如果左边的右边的操作数是true;短路意味着如果左操作数是false,则右操作数不会被评估,因为答案在该点是已知的。

你应该阅读部分15.23和JLS的15.24了解更多详情:

的条件和操作& &就像&(§15.22.2),但评估其右边的操作数只有当其左手操作数的值为true。

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

+0

谢谢......明白了......有区别...我必须练习这使它成为'具体':-) –

1

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

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

在Java中,运营商和|&不仅位运算符(当应用于整数参数),也不管第一值的计算结果两个操作数的非短路逻辑运算符。

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就是如此。

这是否回答你的问题?

1

&和& &要求双方都是正确的,所以代码的行为如预期。

唯一的区别是,&执行双方,但& &仅执行第一如果是假的,因为右边的会是风马牛不相及的最终结果。

这样做的效果是对于像

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

代码很重要,如果你使用会抛出一个NPE | obj为null。

+0

这是一条滑溜的鱼...... ;-) –

+0

将变量换成布尔值后变得很清晰:-) –

2

当与boolean被使用过,按位运算符(|&)是除了类似到逻辑运算符(||&&):

  • &&的情况下,如果第一个参数是false第二个是未评估的,因为整个表达式必须是false。对于&,两个参数都进行评估。

  • ||的情况下,如果第一个参数是true第二留下未计算的,这是因为整个表达随后必须true。对于|,两个参数都进行评估。

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


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

+0

** tl; dr **:按位('|'和'&')运算符评估两个参数,无论如何;逻辑运算符('||'和'&&')*可以*(但不总是)短路。 – NullUserException

+0

@NullUserException他们什么时候不短路? – arshajii

+0

在OP的例子中,它没有短路。 – NullUserException