我只是想知道为什么我们通常在两个布尔值之间使用逻辑OR ||,而不是按位或|,尽管它们都工作得很好。

我的意思是,看看下面这些:

if(true  | true)  // pass
if(true  | false) // pass
if(false | true)  // pass
if(false | false) // no pass
if(true  || true)  // pass
if(true  || false) // pass
if(false || true)  // pass
if(false || false) // no pass

我们可以用|代替||吗?&和&&也是一样。


当前回答

|在布尔表达式中不做短路计算。如果第一个操作数为真,||将停止求值,但|不会。

此外,|可用于对字节/短/int/长值执行按位或操作。| |不能。

其他回答

一个主要的区别是||和&&表现出“短路”,所以RHS只在需要时进行评估。

如。

if (a || b) {
    path1...
} else {
    path2..
}

如果a为真,则不会测试b,并执行path1。如果使用|,则即使'a'为真,两边也将被求值。

看这里和这里,了解更多信息。

希望这能有所帮助。

非短路是有用的。有时你想确保两个表达式都有值。例如,假设您有一个从两个单独的列表中删除对象的方法。你可能想这样做:

class foo {

    ArrayList<Bar> list1 = new ArrayList<Bar>();
    ArrayList<Bar> list2 = new ArrayList<Bar>();

    //Returns true if bar is removed from both lists, otherwise false.
    boolean removeBar(Bar bar) {
        return (list1.remove(bar) & list2.remove(bar));
    }
}

如果您的方法改为使用条件操作数,如果第一个列表返回false,则它将无法从第二个列表中删除对象。

//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
    return (list1.remove(bar) && list2.remove(bar));
}

它并不是特别有用,并且(与大多数编程任务一样)您可以通过其他方法实现它。但这是位操作数的一个用例。

||是逻辑或运算符,|是位或运算符。

boolean a = true;
boolean b = false;

if (a || b) {
}

int a = 0x0001;
a = a | 0x0002;

除了短路之外,另一件需要记住的事情是,对可能不是0或1的值执行位逻辑操作与条件逻辑具有非常不同的含义。虽然|和||通常是一样的,但使用&和&&你会得到非常不同的结果(例如2 & 4是0/假,而2 && 4是1/真)。

如果你从一个函数中得到的东西实际上是一个错误代码,而你正在测试非0,这可能会很重要。

在Java中,这不是一个大问题,因为你必须显式地将类型转换为布尔值或与0进行比较,但在其他具有类似语法的语言(C/ c++等)中,这可能相当令人困惑。

另外,请注意&和|只能应用于整数类型的值,而不是所有可以等效于布尔测试的值。同样,在非java语言中,有相当多的东西可以用作带有隐式!= 0比较的布尔值(指针、浮点数、带有操作符bool()的对象等),而位操作符在这些上下文中几乎总是毫无意义的。

仔细阅读本主题后,我仍然不清楚使用|作为逻辑运算符是否符合Java模式实践。

我最近修改了一个pull请求中的代码

if(function1() | function2()){
  ...
}

必须改为

boolean isChanged = function1();
isChanged |= function2();
if (isChanged){
  ...
}

实际接受的版本是什么?

Java文档没有提到|是逻辑上非短路的OR运算符。

对投票不感兴趣,更感兴趣的是找出标准?! 两个代码版本都按照预期进行编译和工作。