我一直认为Java中的&&操作符用于验证其布尔操作数是否为真,并且&操作符用于对两个整数类型进行逐位操作。

最近我知道&运算符也可以用来验证它的两个布尔操作数是否为真,唯一的区别是即使LHS操作数为假,它也会检查RHS操作数。

Java中的&操作符内部重载吗?或者这背后还有其他的概念吗?


当前回答

如JLS(15.22.2)中所述:

When both operands of a &, ^, or | operator are of type boolean or Boolean, then the type of the bitwise operator expression is boolean. In all cases, the operands are subject to unboxing conversion (§5.1.8) as necessary. For &, the result value is true if both operand values are true; otherwise, the result is false. For ^, the result value is true if the operand values are different; otherwise, the result is false. For |, the result value is false if both operand values are false; otherwise, the result is true.

“诀窍”在于&是一个整数位运算符,也是一个布尔逻辑运算符。为什么不呢,把这个作为运算符重载的例子是合理的。

其他回答

对于AND运算符和OR运算符,Java有两类求值,即Short-Circuit求值和full求值。

&& ||短路评估

短路求值使您可以不计算AND和OR表达式的右边,当整体结果可以从左边的值预测时。

int numberOne = 1;
int numberTwo = 2;
boolean result = false;

// left-side is false so the the overall result CAN be predicted without evaluating the right side.
// numberOne will be 1, numberTwo will be 2, result will be false
result = (numberOne > numberTwo) && (++numberOne == numberTwo);

System.out.println(numberOne); // prints 1
System.out.println(numberTwo); // prints 2
System.out.println(result);    // prints false


// left-side is true so the the overall result CAN NOT be predicted without evaluating the right side.
// numberOne will be 2, numberTwo will be 2, result will be true
result = (numberTwo > numberOne) && (++numberOne == numberTwo);

System.out.println(numberOne); // prints 2
System.out.println(numberTwo); // prints 2
System.out.println(result);    // prints true

^全面评估

虽然在某些情况下可以预测结果,但有必要计算右边的值。

int numberOne = 1;
int numberTwo = 2;
boolean result = false;

// left-side is false so the the overall result will be false BUT the right side MUST be evaluated too.
// numberOne will be 2, numberTwo will be 2, result will be false
result = (numberOne > numberTwo) & (++numberOne == numberTwo);

System.out.println(numberOne); // prints 2
System.out.println(numberTwo); // prints 2
System.out.println(result);    // prints false

注意:

Notice that for XOR (^) there is no short-circuit, because both sides are always required to determine the overall result. Notice that other possible names for Short-Circuit evaluation are minimal evaluation and McCarthy evaluation. It is not recommenced to mix boolean logic and actions in the same expression & can also act as a Bitwise AND operator which is very academic and can be used in cryptography. When both bits are 1, the result is 1, or either of the bits is not 1, the result is 0. (Check the following code)

AND位的例子:

byte a = 5;              // 00000101
byte b = 3;              // 00000011
byte c = (byte) (a & b); // 00000001 (c is 1)

如JLS(15.22.2)中所述:

When both operands of a &, ^, or | operator are of type boolean or Boolean, then the type of the bitwise operator expression is boolean. In all cases, the operands are subject to unboxing conversion (§5.1.8) as necessary. For &, the result value is true if both operand values are true; otherwise, the result is false. For ^, the result value is true if the operand values are different; otherwise, the result is false. For |, the result value is false if both operand values are false; otherwise, the result is true.

“诀窍”在于&是一个整数位运算符,也是一个布尔逻辑运算符。为什么不呢,把这个作为运算符重载的例子是合理的。

这取决于参数的类型……

对于整数参数,单个&号(“&”)是“逐位AND”操作符。双&号(“&&”)只用于两个布尔参数。

对于布尔参数,单个&号构成(无条件)“逻辑与”运算符,而双&号(“&&”)是“条件逻辑与”运算符。也就是说,单&号总是计算两个参数,而双&号只在第一个参数为真时计算第二个参数。

对于所有其他参数类型和组合,应该发生编译时错误。

boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE

&&和||称为短路算子。当使用它们时,对于|| -如果第一个操作数求值为true,则其余操作数不求值。对于&& -,如果第一个操作数求值为false,其余的操作数根本不被求值。

所以if (a || (++x > 0))在这个例子中,如果a为真,变量x不会增加。