【问题标题】:Effect of a Bitwise Operator on a Boolean in JavaJava 中按位运算符对布尔值的影响
【发布时间】:2010-12-16 00:04:13
【问题描述】:

按位运算符应该移动变量并一点一点地对它们进行操作。在整数、长整数、字符的情况下,这是有道理的。这些变量可以包含由其大小强制执行的所有值范围。

然而,在布尔值的情况下,一个布尔值只能包含两个值。 1 = 真或 0 = 假。但是布尔值的大小没有定义。它可以大到一个字节,也可以小到一点。

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

【问题讨论】:

  • 我认为你不能在布尔值上使用按位运算符。只看数字。肯定~不行,不知道其他运营商怎么样。
  • 你可以使用其中的一些,我们刚刚发现了一个 |在我们的遗留代码中使用。我们正在删除它,但此代码已编译并运行。
  • 因为一个短路而另一个不是(见 mobrule 的回答),在你改变 |到 ||您可能希望确保后续的布尔表达式没有原始程序员打算始终执行的任何副作用。

标签: java boolean bitwise-operators


【解决方案1】:

当操作数是原始整数类型时,运算符&^| 是按位运算符。当操作数是布尔值时,它们是逻辑运算符,并且它们在后一种情况下的行为是指定的。详情请参阅Java Language Specification 的第 15.22.2 节。

【讨论】:

  • 特别是 & 和 ^ 和 |是非短路逻辑布尔运算符。
  • 如果上面是真的,为什么ideone.com/oGSF7c会抛出空指针异常呢?如果|= 操作符是合乎逻辑的,那么程序不应该运行x.getValue() 指令。
  • @JohnKrommidas,您的 x 为空,这就是您收到 NullPointerException 的原因。你需要实例化它。
  • @Ben,这就是重点。如果操作是按位的,VM 就不会费心检查语句的第二部分。由于它确实检查它,因此操作不能按位进行。
  • @Ben,正如@Ken 所说,逻辑是非短路的,因此评估第二部分。因此,如果 x 为空,a || x.foo() 是安全的,但 a | x.foo() 不是。 |= 遵循与 | 相同的规则。
【解决方案2】:

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

the precedence table 中提取(最高优先级在顶部)。

bitwise AND                 &
bitwise exclusive OR        ^
bitwise inclusive OR        |
logical AND                 &&
logical OR                  ||

这对您意味着什么?

绝对没有,只要您坚持仅使用 &| 或仅使用 &&||

但是,由于| 的优先级高于&&(与|| 相比,|| 的优先级较低),随意混合它们可能会导致意外行为。

所以a && b | c && da && (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 -|

如果您希望 OR 的优先级高于 AND,您可以同时使用 |&&,但不建议这样做。

但您确实应该将它们放在括号中以在使用不同符号时澄清优先级,即(a && b) || c(括号以澄清优先级),a && b && c(不需要括号)。

【讨论】:

    【解决方案3】:

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

    boolean b = booleanExpression1() && booleanExpression2();
    boolean b = booleanExpression1() & booleanExpression2();
    

    如果booleanExpression1() 评估为false,则
    booleanExpression2() 在第一种情况下不会被评估,并且
    booleanExpression2()(以及它可能产生的任何副作用)是 在第二种情况下进行评估,

    【讨论】:

    • 而按位运算通常执行faster than the short-circuit one(只要求值简单)
    • 按位& 会更快,但使用&& 可以忽略对第二个函数的调用
    【解决方案4】:

    即使它会起作用,你也不应该这样做。仅当两个操作数都是原始整数类型或两者都是布尔类型时,语言规范才定义按位运算符。我会说对于任何其他情况,结果都没有定义:

    http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5228

    【讨论】:

    • 问题关于布尔值,而不是关于基元或基元和布尔值的混合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 2010-09-06
    • 2015-10-22
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多