Java的boolean |=运算符

28

最近我看到了一段使用了这个的代码:

boolean val = something();
val |= somethingElse();

有意思的部分是在布尔原始类型上使用了类似于二进制的 |= 运算符。

让我很惊讶的是,布尔类型中存在 |=,就好像它是整数类型一样。我查找了Java规范以寻找这个运算符,但没有找到任何相关信息。

如果左值已经为 true,是否会评估右操作数,这让我很好奇。

有人可以指引我查看Java规范中有关此运算符的内容吗?


4
这只是 val = val | somethingElse(); // somethingElse() 应返回布尔值。这是一个标准的 OR。 - Sudhanshu Umalkar
@SudhanshuUmalkar OP 知道这一点,他要求在文档中提供规格说明。 - Juvanis
1
答案在这里,伙计们:https://dev59.com/QXE95IYBdhLWcg3wCJbk - Juvanis
我以为布尔表达式只有 ||,所以我期望像 ||= 这样的运算符。在布尔值上使用二进制 | 有意义吗? - Pointer Null
没有快捷评估,尽管没有明确提到。只有在 || 处才明确提到了快捷逻辑。 - Joop Eggen
1
@Sudhanshu 这不是标准的 OR,而是位运算 OR 操作符(与布尔运算符相对)。它也是一种积极的操作符,而不是短路操作符(如布尔运算符)。 - xagyg
5个回答

36

根据JLS:

15.26.2. 复合赋值运算符

形如 E1 op= E2 的复合赋值表达式等同于 E1 = (T) ((E1) op (E2)),其中 TE1 的类型,但是 E1 只被计算一次。

15.22.2. 布尔逻辑运算符 &, ^|

&, ^, 或者 | 运算符的两个操作数都是 booleanBoolean 类型时,位运算符表达式的类型就是 boolean。在所有情况下,必要时操作数都会进行拆箱转换(§5.1.8)。

对于 |,如果两个操作数的值都是 false,则结果值为 false;否则,结果为 true。

这意味着

val |= somethingElse();

严格等同于

val = val | somethingElse();

(假设somethingElse()返回booleanBoolean)。

如果左值已经为true,我很好奇右操作数是否会被评估。

是的,它将被评估,因为|不会短路:

15.7.2.在执行操作之前评估操作数

Java编程语言保证运算符的每个操作数(除了条件运算符&&||? :)在执行操作本身的任何部分之前都被完全评估。

15.24.条件或运算符||

因此,||计算与booleanBoolean操作数上的|相同的结果。它仅在右操作数表达式有条件地而不总是被评估时有所不同。


val |= somethingElse();在Kotlin中没有等效的语句。我很好奇为什么... - TheBigBadBoy

4

3
位运算逻辑运算符在布尔类型上的效果与“正常”的逻辑运算符相同。
Java语言规范 15.22节中得知:
当一个 &、^ 或 | 运算符的两个操作数都是布尔类型或 Boolean 类型时,位运算符表达式的类型为布尔类型。在所有情况下,必要时操作数都会进行拆箱转换(§5.1.8)。
对于 &,如果两个操作数的值都为 true,则结果值为 true;否则,结果为 false。
对于 ^,如果操作数的值不同,则结果值为 true;否则,结果为 false。
对于 |,如果两个操作数的值都为 false,则结果值为 false;否则,结果为 true。
唯一的区别在于位运算符不能用于短路求值。
例如,这段代码将抛出 NullPointerException:
Boolean b1 = new Boolean(true);
Boolean b2 = null;
if (b1 || b2) {
    //no null pointer here;
}
if (b1 | b2) {
    //null pointer here;
}

2
>>I'd be curious if right operand is evaluated if left value already is true.

按位运算符(如|&等)在完成前会对两侧进行评估。

逻辑运算符(如&&||等)在某些情况下可以跳过第二部分的评估。这被称为短路


-1

它不是二进制,而是“或”逻辑语句的意思

 val |= {something else} 

等同于布尔表达式:

val == val or {something else} 

这里的or指的是数学表达式和计算机科学中使用的或运算符。

在一些编程语言中,或运算符用两个||符号表示,在另一些语言中则用一个|符号表示,其中SQL以及我所知道的所有数据库语言(DTD、JSON等)都采用了单竖线的形式。


“|”不是条件或(“||”),而是按位或。因此,“val |= something”与“val = val | something”相同。 - renardesque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接