我只是想知道为什么我们通常在两个布尔值之间使用逻辑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

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


当前回答

当我遇到这个问题时,我创建了测试代码来了解这个问题。

public class HelloWorld{

   public static boolean bool(){
      System.out.println("Bool");
      return true;
   }

   public static void main(String []args){

     boolean a = true;
     boolean b = false;

     if(a||bool())
     {
        System.out.println("If condition executed"); 
     }
     else{
         System.out.println("Else condition executed");
     }

 }
}

在这种情况下,我们只改变if条件的左边值加上a或b。

||场景,当左侧为true时[if(a||bool())]

输出"If条件已执行"

||场景,当左边为false [if(b||bool())]

输出-

Bool
If condition executed

||结论当使用||时,右侧只检查左侧为假。

|场景,当左侧为true时[if(a|bool())]

输出-

Bool
If condition executed

|场景,当左侧为false [if(b|bool())]

输出-

Bool
If condition executed

|结论使用|时,请同时检查左右两侧。

其他回答

除了短路之外,另一件需要记住的事情是,对可能不是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运算符。

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

来看看:

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html

|是位包含或

||为逻辑或

|是位运算符:||是短路运算符——当一个元素为假时,它将不检查其他元素。

 if(something || someotherthing)
 if(something | someotherthing)

如果某个值为TRUE, ||将不会计算另一个值,而|可以。如果If语句中的变量实际上是函数调用,那么使用||可能会节省大量性能。

因此,在其他答案的基础上,举个例子,短路在以下防御性检查中至关重要:

if (foo == null || foo.isClosed()) {
    return;
}

if (bar != null && bar.isBlue()) {
    foo.doSomething();
}

使用|和&可能导致在这里抛出NullPointerException。