位运算符用于对变量进行逐位操作。对于整数、长整数和字符,这是有意义的。这些变量可以包含其大小所强制的完整值范围。
然而,在布尔值的情况下,布尔值只能包含两个值。1 = true或0 = false。但是布尔值的大小没有定义。它可以像一个字节那样大,也可以像一个比特那样小。
那么,在布尔值上使用位运算符有什么效果呢?JVM是否将其转换为普通的逻辑运算符并继续执行?它是否将布尔值视为单个比特实体以用于运算?还是结果未定义,就像布尔值的大小一样?
位运算符用于对变量进行逐位操作。对于整数、长整数和字符,这是有意义的。这些变量可以包含其大小所强制的完整值范围。
然而,在布尔值的情况下,布尔值只能包含两个值。1 = true或0 = false。但是布尔值的大小没有定义。它可以像一个字节那样大,也可以像一个比特那样小。
那么,在布尔值上使用位运算符有什么效果呢?JVM是否将其转换为普通的逻辑运算符并继续执行?它是否将布尔值视为单个比特实体以用于运算?还是结果未定义,就像布尔值的大小一样?
当操作数为基本整型时,运算符 &
, ^
, 和 |
是按位运算符。当操作数为布尔值时,它们是逻辑运算符,并且其行为在这种情况下是指定的。请参阅Java语言规范第15.22.2节以获取详细信息。
a || x.foo()
是安全的,但a | x.foo()
则不安全。|=
遵循与|
相同的规则。 - Michael Smith使用位运算符可以规避短路行为:
boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();
如果booleanExpression1()
的计算结果为false
,则在第一种情况下不会评估booleanExpression2()
,而在第二种情况下将评估booleanExpression2()
(及其可能有的任何副作用)。&
会更快,但使用&&
可以忽略对第二个函数的调用。 - NatNgs除了其他答案中涵盖的内容外,值得注意的是&&
和||
与&
和|
具有不同的优先级。
摘自优先级表(优先级最高的在顶部)。
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||
这对你意味着什么?
只要你坚持只使用&
和|
或者只使用&&
和||
,那就没有任何问题。
但是,由于|
的优先级高于&&
(与||
相反,其优先级较低),自由混合它们可能会导致意外行为。
因此,a && b | c && d
与a && (b | c) && d
是相同的,
而a && b || c && d
则是(a && b) || (c && d)
。
为了证明它们不同,请考虑来自真值表的一部分:
a | b | c | d | (b|c) | (a&&b) | (c&&d) | a && (b|c) && d | (a&&b) || (c&&d)
F | T | T | T | T | F | T | F | T
^ ^
|- not the same -|
|
和 &&
结合起来,但这不被推荐。(a && b) || c
(用括号澄清优先级),a && b && c
(不需要括号)。