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

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


当前回答

||通过OR'ing两个值返回布尔值(这就是为什么它被称为逻辑或)

IE:

if (A || B) 

如果A或B中有一个为真则返回真,如果它们都为假则返回假。

|是一个对两个值执行位操作的运算符。为了更好地理解位操作,你可以阅读这里:

http://en.wikipedia.org/wiki/Bitwise_operation

其他回答

||是逻辑或,|是位或。

其他答案很好地涵盖了运算符之间的函数差异,但这些答案可以适用于目前存在的几乎每一种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编程的高层中根本无法进行比较。

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

boolean a = true;
boolean b = false;

if (a || b) {
}

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

|是位操作符。||是逻辑运算符。

一个会取两个比特或者它们。

一个人将决定真理(这个或那个)如果这个是真的或那个是真的,那么答案就是真的。

哦,该死的人回答这些问题很快。

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

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

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

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