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

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


当前回答

有很多用例表明为什么你应该选择||而不是|。有些用例必须使用|操作符来检查所有条件。

例如,如果您希望检查表单验证,并且希望向用户显示所有带有错误文本的无效字段,而不仅仅是第一个无效字段。

||算子是,

   if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

   private boolean checkIfEmpty(Widget field) {
      if(field.isEmpty()) {
        field.setErrorMessage("Should not be empty!");
        return true;
      }
      return false;
   }

因此,在上面的代码片段中,如果用户提交的表单中所有字段都是空的,那么只有nameField将显示错误消息。但是,如果你把它改成,

   if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

无论真实情况如何,它都会在每个字段上显示正确的错误信息。

其他回答

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

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

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

其他答案很好地涵盖了运算符之间的函数差异,但这些答案可以适用于目前存在的几乎每一种c派生语言。这个问题带有java的标签,因此我将努力具体地、从技术上回答java语言。

&和|可以是整数位运算符,也可以是布尔逻辑运算符。按位运算符和逻辑运算符(§15.22)的语法是:

AndExpression:
  EqualityExpression 
  AndExpression & EqualityExpression

ExclusiveOrExpression:
  AndExpression 
  ExclusiveOrExpression ^ AndExpression

InclusiveOrExpression:
  ExclusiveOrExpression 
  InclusiveOrExpression | ExclusiveOrExpression

The syntax for EqualityExpression is defined in §15.21, which requires RelationalExpression defined in §15.20, which in turn requires ShiftExpression and ReferenceType defined in §15.19 and §4.3, respectively. ShiftExpression requires AdditiveExpression defined in §15.18, which continues to drill down, defining the basic arithmetic, unary operators, etc. ReferenceType drills down into all the various ways to represent a type. (While ReferenceType does not include the primitive types, the definition of primitive types is ultimately required, as they may be the dimension type for an array, which is a ReferenceType.)

位运算符和逻辑运算符具有以下属性:

这些运算符具有不同的优先级,&具有最高优先级,|具有最低优先级。 这些操作符在语法上都是左关联的(每个组从左到右)。 如果操作数表达式没有副作用,每个操作符都是可交换的。 每个运算符都是结合的。 位运算符和逻辑运算符可用于比较数值类型的两个操作数或布尔类型的两个操作数。所有其他情况都会导致编译时错误。

操作符是位操作符还是逻辑操作符的区别取决于操作数是“可转换为基本整型”(§4.2)还是boolean或boolean类型(§5.1.8)。

如果操作数是整型,则对两个操作数执行二进制数字提升(§5.6.2),将它们都保留为长型或整型。操作的类型将是(提升的)操作数的类型。此时,&将是按位与,^将是按位异或,|将是按位异或。(§15.22.1)

如果操作数是布尔型或布尔型,操作数将在必要时进行开箱转换(§5.1.8),操作类型将为布尔型。如果两个操作数都为真,&将返回真;如果两个操作数不同,^将返回真;如果其中一个操作数为真,|将返回真。(§15.22.2)

相反,&&是“条件与操作符”(§15.23),||是“条件与操作符”(§15.24)。它们的语法定义为:

ConditionalAndExpression:
  InclusiveOrExpression 
  ConditionalAndExpression && InclusiveOrExpression

ConditionalOrExpression:
  ConditionalAndExpression 
  ConditionalOrExpression || ConditionalAndExpression

&&类似于&,除了它只在左操作数为真时计算右操作数。||类似于|,除了它只在左操作数为false时计算右操作数。

条件-并且具有以下属性:

The conditional-and operator is syntactically left-associative (it groups left-to-right). The conditional-and operator is fully associative with respect to both side effects and result value. That is, for any expressions a, b, and c, evaluation of the expression ((a) && (b)) && (c) produces the same result, with the same side effects occurring in the same order, as evaluation of the expression (a) && ((b) && (c)). Each operand of the conditional-and operator must be of type boolean or Boolean, or a compile-time error occurs. The type of a conditional-and expression is always boolean. At run time, the left-hand operand expression is evaluated first; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8). If the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated. If the value of the left-hand operand is true, then the right-hand expression is evaluated; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8). The resulting value becomes the value of the conditional-and expression. Thus, && computes the same result as & on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

条件-或具有以下属性:

The conditional-or operator is syntactically left-associative (it groups left-to-right). The conditional-or operator is fully associative with respect to both side effects and result value. That is, for any expressions a, b, and c, evaluation of the expression ((a) || (b)) || (c) produces the same result, with the same side effects occurring in the same order, as evaluation of the expression (a) || ((b) || (c)). Each operand of the conditional-or operator must be of type boolean or Boolean, or a compile-time error occurs. The type of a conditional-or expression is always boolean. At run time, the left-hand operand expression is evaluated first; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8). If the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8). The resulting value becomes the value of the conditional-or expression. Thus, || computes the same result as | on boolean or Boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

简而言之,正如@JohnMeagher在评论中反复指出的那样,&和|实际上在操作数为布尔或布尔的特定情况下是非短路布尔操作符。通过良好的实践(即:没有次要影响),这是一个微小的差异。然而,当操作数不是布尔值或布尔值时,操作符的行为就大不相同了:位操作和逻辑操作在Java编程的高层中根本无法进行比较。

| =位或,|| =逻辑或

1).(expression1 | expression2), |运算符将计算expression2,而不管expression1的结果是真还是假。

例子:

class Or 
{
    public static void main(String[] args) 
    {
        boolean b=true;

        if (b | test());
    }

    static boolean test()
    {
        System.out.println("No short circuit!");
        return false;
    }
}

2).(expression1 || expression2),如果expression1为真,||操作符将不计算expression2。

例子:

class Or 
{
    public static void main(String[] args) 
    {
        boolean b=true;

        if (b || test())
        {
            System.out.println("short circuit!");
        }
    }

    static boolean test()
    {
        System.out.println("No short circuit!");
        return false;
    }
}

逻辑||和&&只在必要时检查右边。|和&每次检查两边。

例如:

int i = 12;
if (i == 10 & i < 9) // It will check if i == 10 and if i < 9
...

重写:

int i = 12;
if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i != 10
...

另一个例子:

int i = 12;
if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10
...

重写:

int i = 12;
if (i == 12 || i > 10) // It will check if i == 12, it does, so it stops checking and executes what is in the if statement
...