可能重复:
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 );
}
}
答案 0 :(得分:11)
不,绝对没有。我不明白。短路不应该成功,因为等式的左边等于1?
&&
的要点是,如果左侧和右侧操作数为true
,则结果仅为true
;短路意味着如果左操作数为false
,则不评估右操作数,因为答案在该点已知。
条件和操作员&&就像& (§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
,这不是真的,所以false
是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}} {{1}} 1}}是。
这会回答你的问题吗?