Java 布尔值 |= 运算符
Posted
技术标签:
【中文标题】Java 布尔值 |= 运算符【英文标题】:Java boolean |= operator 【发布时间】:2013-03-02 22:00:25 【问题描述】:最近我看到一个使用这个的代码:
boolean val = something();
val |= somethingElse();
有趣的部分是在布尔原始类型上创建的 |=(类似二进制)运算符。
令我惊讶的是,布尔值存在 |=,就好像它是整数类型一样,并在 Java 规范中搜索该运算符,但找不到。
如果左值已经为真,是否会评估右操作数。
有人可以指出我的 Java 规范吗?
【问题讨论】:
只是 val = val |别的东西(); // somethingElse() 期望返回布尔值。这是一个标准的 OR @SudhanshuUmalkar OP 知道这一点,他要求在文档中提供规范。 答案在这里,伙计们:***.com/q/2486472/544983 我以为只有||对于布尔表达式,所以我希望像 ||= 这样的运算符。制作二进制有意义吗?在布尔值上? @Sudhanshu 这不是标准的 OR,它是按位 OR 运算符(与布尔运算符相反)。它也是一个积极的运算符,而不是短路运算符(例如布尔运算符)。 【参考方案1】:来自 JLS:
15.26.2. Compound Assignment Operators
E1 op= E2
形式的复合赋值表达式等价于E1 = (T) ((E1) op (E2))
,其中T
是E1
的类型,但E1
只计算一次。15.22.2. Boolean Logical Operators
&
,^
, and|
当
&
、^
或|
运算符的两个操作数均为boolean
或Boolean
类型时,则按位运算符表达式的类型为boolean
。在所有情况下,操作数都会根据需要进行拆箱转换(第 5.1.8 节)。对于
|
,如果两个操作数值都为假,则结果值为假;否则,结果为真。
这意味着
val |= somethingElse();
严格等价于
val = val | somethingElse();
(假设somethingElse()
返回boolean
或Boolean
)。
如果左值已经为真,我会很好奇是否计算右操作数。
是的,它会被评估,因为|
不会短路:
15.7.2. Evaluate Operands before Operation
Java 编程语言保证运算符的每个操作数(条件运算符
&&
、||
和? :
除外)似乎在操作本身的任何部分执行之前都已被完全评估。15.24. Conditional-Or Operator
||
因此,
||
在boolean
或Boolean
操作数上计算与|
相同的结果。不同之处仅在于右侧操作数表达式是有条件地计算而不是总是计算。
【讨论】:
val |= somethingElse();
在 Kotlin 中没有等价物。我想知道为什么...【参考方案2】:
有关|
的定义,请参见http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.2。有关|=
的定义,请参见http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.2。这些定义正是您的想法。
令我惊讶的是缺少||=
运算符。
【讨论】:
【参考方案3】:按位逻辑运算符与布尔值上的“普通”逻辑运算符具有相同的效果。
来自Java Language Specification15.22:
当 &、^ 或 | 的两个操作数运算符的类型为布尔型或 布尔型,则按位运算符表达式的类型为布尔型。 在所有情况下,操作数都需要进行拆箱转换(§5.1.8) 根据需要。
对于&,如果两个操作数都为真,则结果值为真; 否则结果为假。
对于^,如果操作数的值不同,则结果值为真; 否则结果为假。
对于|,如果两个操作数的值都为假,则结果值为假; 否则,结果为真。
唯一真正的区别是位运算符不能用于短路评估。
比如这段代码会抛出NullPointerException
:
Boolean b1 = new Boolean(true);
Boolean b2 = null;
if (b1 || b2)
//no null pointer here;
if (b1 | b2)
//null pointer here;
【讨论】:
【参考方案4】:>>I'd be curious if right operand is evaluated if left value already is true.
按位运算符(如|
、&
、..)在完成之前评估两边。
在某些情况下,逻辑运算符(如&&
、||
、..)可以跳过第二部分的评估。这称为short-circuit
。
【讨论】:
【参考方案5】:它不是二进制的,它是一个“或”逻辑语句的意思
val |= something else
与布尔表达式相同:
val == val or something else
包含或(数学表达式和计算机科学中使用的正则或)
在某些编程语言中或被两个 ||标志和一些由一个|其中之一是 SQL 和我所知道的 DTD JSON 等所有数据库语言。
【讨论】:
以上是关于Java 布尔值 |= 运算符的主要内容,如果未能解决你的问题,请参考以下文章