我一直认为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)

除了&&和||是短路外,在混合这两种形式时,还要考虑运算符优先级。 我认为每个人都不会立即看出result1和result2包含不同的值。

boolean a = true;
boolean b = false;
boolean c = false;

boolean result1 = a || b && c; //is true;  evaluated as a || (b && c)
boolean result2 = a  | b && c; //is false; evaluated as (a | b) && c

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

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

对于布尔值,两者之间没有输出差异。你可以交换&&和&或||和|,它永远不会改变表达式的结果。

区别在于处理信息的场景背后。当你对a= 0和b = 1的表达式“(a != 0) & (b != 0)”进行右转时,会发生以下情况:

left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false

当你写一个表达式(a != 0) && (b != 0)当a= 0和b = 1时,会发生以下情况:

a != 0 -->false
expression returns false

更少的步骤,更少的处理,更好的编码,特别是在处理许多布尔表达式或复杂的参数时。

所有的答案都很棒,似乎不需要更多的答案了 但我只是想指出关于&&算子的一些东西,叫做依赖条件

在使用运算符&&的表达式中,一个条件——我们称之为依赖条件——可能需要另一个条件为真,以使依赖条件的求值有意义。

在这种情况下,依赖条件应该放在&&运算符之后以防止错误。

考虑表达式(i != 0) && (10 / i == 2)。依赖条件(10 / i == 2)必须出现在&&运算符之后,以防止被零除的可能性。

另一个例子(myObject != null) && (myObject. getvalue () == somevaluse)

还有一件事:&&和||被称为短路求值,因为只有当第一个参数不足以确定表达式的值时,才会执行或求值第二个参数

参考资料:Java™如何编程(早期对象),第十版