Java中逐位运算符对布尔值的影响

Java中逐位运算符对布尔值的影响,java,boolean,bitwise-operators,Java,Boolean,Bitwise Operators,按位运算符应该移动变量并逐位对其进行操作。对于整数、long、chars,这是有意义的。这些变量可以包含由其大小强制执行的完整值范围 但是,对于布尔型,布尔型只能包含两个值。1=真或0=假。但是布尔值的大小没有定义。它可以大到一个字节,也可以小到一位 那么,在布尔值上使用位运算符有什么效果呢?JVM本质上是否将其转换为普通的逻辑运算符并继续?为了操作的目的,它是否将布尔值视为一个单位实体?或者结果与布尔值的大小一起未定义?即使它可以工作,也不应该这样做。语言规范仅在两个操作数都是基元整数类型或都

按位运算符应该移动变量并逐位对其进行操作。对于整数、long、chars,这是有意义的。这些变量可以包含由其大小强制执行的完整值范围

但是,对于布尔型,布尔型只能包含两个值。1=真或0=假。但是布尔值的大小没有定义。它可以大到一个字节,也可以小到一位


那么,在布尔值上使用位运算符有什么效果呢?JVM本质上是否将其转换为普通的逻辑运算符并继续?为了操作的目的,它是否将布尔值视为一个单位实体?或者结果与布尔值的大小一起未定义?

即使它可以工作,也不应该这样做。语言规范仅在两个操作数都是基元整数类型或都是布尔类型时定义位运算符。我想说,对于任何其他情况,结果都没有定义:


当操作数是基元整数类型时,运算符
&
^
|
是位运算符。当操作数为布尔值时,它们是逻辑运算符,并指定了后一种情况下它们的行为。有关详细信息,请参阅的第15.22.2节。

使用位运算符可以避免短路行为:

boolean b = booleanExpression1() && booleanExpression2();
boolean b = booleanExpression1() & booleanExpression2();
如果
booleanExpression1()
的计算结果为
false
,则
booleanExpression2()
在第一种情况下不计算,并且

booleanExpression2()
(以及它可能产生的任何副作用)在第二种情况下进行了评估,

除了其他答案中所涵盖的内容之外,值得注意的是
&
|
的优先级与
&
不同

从中提取(在顶部具有最高优先级)

这对你意味着什么?

绝对没有,只要你坚持只使用
&
或者只使用
&

但是,由于
|
的优先级高于
&&
(与优先级较低的
|
相反)​, 随意混合会导致意外行为

因此
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
(不需要括号)。

我认为不能对布尔值使用位运算符。只看数字。我确信~将不起作用,我不知道其他运算符如何。您可以使用其中一些运算符,我们刚刚发现一个|用于我们的遗留代码。我们正在删除它,但这段代码已编译并运行。由于一个是短路,另一个不是(请参阅mobrule的答案),在将|更改为| |之前,您可能希望确保后续的布尔表达式没有原始程序员希望始终执行的任何副作用。具体而言,&和^和|是非短路逻辑布尔运算符。如果上述为真,为什么要抛出空指针异常?如果
|=
运算符是逻辑运算符,则程序不应运行
x.getValue()
指令。@JohnKrommidas,您的x为null,这就是为什么您会得到NullPointerException。你需要实例化它。@Ben,这就是重点。如果操作是按位的,VM就不会费心检查语句的第二部分。因为它确实检查了它,所以操作不能是按位的。@Ben,正如@Ken所说,逻辑是非短路的,所以第二部分被计算。因此,如果x为null,那么
a | x.foo()
是安全的,但是
a | x.foo()
不是
|=
遵循与
|
相同的规则。按位操作通常执行(只要计算简单),按位
&
将更快,但使用
&
可以忽略对第二个函数的调用问题是关于布尔函数的,不是关于原语或原语与布尔语的混合。
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 -|