为啥 &= 运算符与 && 的工作方式不同

Posted

技术标签:

【中文标题】为啥 &= 运算符与 && 的工作方式不同【英文标题】:Why &= operator doesn't work the same as &&为什么 &= 运算符与 && 的工作方式不同 【发布时间】:2014-09-04 05:51:59 【问题描述】:

我只是好奇 java 是如何工作的。有人能解释一下为什么在案例 1 中调用 getBoolean 而在案例 2 中没有调用吗?

public class Main 

    public static void main(String[] args) 
        System.out.println("---------- Case 1 ----------");
        boolean b = false;
        b &= getBoolean(true);

        System.out.println("---------- Case 2 ----------");
        b = false;
        b = b && getBoolean(true);
    

    private static boolean getBoolean(boolean bool) 
        System.out.println("getBoolean(" + bool + ") was called\n");
        return bool;
    


输出:

---------- Case 1 ----------
getBoolean(true) was called

---------- Case 2 ----------

【问题讨论】:

逻辑与位与 它的工作方式与 & 运算符一样。每个复合运算符都像没有= 的等效运算符一样工作 - 所以+= 就像+-= 就像- 等等。为什么你会期望&=&& @Sneftel - 布尔值的“逻辑”和“按位”没有区别,因为它们只是一个活动位。这里重要的是&& 是短路的,但&&= 不是。 这就是我的意思,是的。 真的吗?因为这根本不是你说的。 【参考方案1】:

b &= ab = b & a 的快捷方式,而不是b = b && a 的快捷方式

这是因为&&& 运算符之间的区别。

& 运算符始终评估条件的两边。

&& 运算符仅在需要时评估第二个。

所以,getBoolean(true) 不会在第二种情况下运行。

【讨论】:

+1,加上原因,b &= a等于b = b & a而不是b = b && a【参考方案2】:

在情况 2 中,getBoolean(true); 未被评估,因为 && 是一个短路运算符,例如如果表达式为false,则停止计算

案例 1 只是将 getBoolean() 方法的结果设置为 b 变量。


更新,感谢@KisHan:

注意b &= a 等于b = b & a 而不是b = b && a

【讨论】:

这个可以加在答案里,b &= a等于b = b & a不是b = b && a【参考方案3】:

在第二种情况下,bfalse,对于&&,如果第一个条件为假,则不会继续前进。

 b = b && getBoolean(true);//b is false

所以&&(逻辑与)首先检查左边的运算,如果是truecontinues右边。

&(Bitwise AND) 运算符计算表达式的两边,因为它是 bitwise AND 运算符。因为它在左侧和右侧之间执行 AND 运算。

所以在第一种情况下

b = b & getBoolean(true);//will perform AND operation to evaluate Expression

【讨论】:

【参考方案4】:

在第一种情况下,它是按位的并试图获取分配的值 (getBoolean())。

在第二种情况下,&& 执行short circuit evaluation。如果第一个表达式为假,则第二个表达式不会计算。

只有在第一个参数不足以确定表达式的值时才执行或评估第二个参数:

b = b && getBoolean(true); // b already false and there is no use even getBoolean(true) is true or false , because the result is already false as b is false.

【讨论】:

【参考方案5】:

& 表示按位与:在逐位级别上,如果两个输入位都为真,它将输出设置为 true&& 表示逻辑与:如果两个输入都为真,则表达式返回真。 && 也是短路的(如果第一个输入是错误的,则停止评估并立即返回 false),这就是您在此处看到的。

【讨论】:

它们是布尔值 - 区分布尔值的“按位”和“逻辑”是没有意义的,因为只有一个有意义的位。 @DavidWallace 谈论“短路按位运算”是没有意义的。 OP 显然不理解按位与逻辑 AND 之间的区别,任何不能解释这里发生的事情的答案都是不完整的。 如果您理解按位与逻辑,那么& 不会短路的事实会立即随之而来。如果你不解释什么是按位与,那么它就没有任何意义。就好像 OP 问道“我不明白为什么用锤子钉钉子比用螺丝刀更容易”,而你没有解释什么是螺丝钉。 如果只有一位,则按位和逻辑没有区别。 && 是按位与逻辑与短路。 & 是按位与逻辑与而不是短路。谈论布尔值的“按位”和“逻辑”完全是一条红鲱鱼。 &&& 是完全不同的操作,布尔值只是一个位的事实并不是重点。这是any_truthy_value & function_call()的特例,完整的答案解释了一般情况。

以上是关于为啥 &= 运算符与 && 的工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Java 没有条件与和条件或运算符的复合赋值版本? (&&=, ||=)

为啥 ( x & 3 ) 与 ( x mod 4 ) 相同?

为啥 && 运算符会产生第二个操作数的类型

为啥 C/C++ 中没有 ^^ 运算符?

当按位运算符做同样的事情时,为啥要使用逻辑运算符?

为啥短原语有赋值运算符(&=、+=)但没有非赋值运算符(&、+)? [复制]