布尔运算符的差异: & vs & & and | vs | |

我知道 &&||的规则,但是什么是 &|?请给我举个例子解释一下。

219034 次浏览

这些是按位 AND 和按位 OR 运算符。

int a = 6; // 110
int b = 4; // 100


// Bitwise AND


int c = a & b;
//   110
// & 100
// -----
//   100


// Bitwise OR


int d = a | b;
//   110
// | 100
// -----
//   110


System.out.println(c); // 4
System.out.println(d); // 6

Thanks to Carlos for pointing out the appropriate section in the Java Language Spec (15.22.1, 15.22.2) regarding the different behaviors of the operator based on its inputs.

实际上,当两个输入都是布尔的时候,这些操作符被认为是布尔逻辑操作符,它们的行为类似于条件-和(&&)和条件-或(||)操作符,只是它们不会短路,所以下面的操作符是安全的:

if((a != null) && (a.something == 3)){
}

这不是:

if((a != null) & (a.something == 3)){
}

“短路”是指操作员不必检查所有条件。在上面的例子中,只有当 a不是 null时,&&才会检查第二个条件(否则整个语句将返回 false,无论如何检查以下条件都是没有意义的) ,因此 a.something的语句不会引发异常,或者被认为是“安全的”

&操作符总是检查子句中的每个条件,因此在上面的示例中,当 a实际上是 null值时,可以计算 a.something,从而引发异常。

运算符 & & 和 | | 是短路的,这意味着如果左表达式的值足以确定结果,它们将不会计算右表达式。

&|是整数类型(例如 int)上的按位运算符: http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

&&||仅在布尔值上运行(正如其他答案已经说过的,它们是短路的)。

提供与运算符相同的结果。区别在于,它们总是计算表达式的两侧,其中 as & & 和 | | 停止计算第一个条件是否足以确定结果。

我认为你说的是两个操作符的逻辑含义,这里你有一个表格-简历:

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

短路求值 、最小求值或麦卡锡求值(在约翰 · 麦卡锡之后)是一些布尔运算符在某些编程语言中的语义,在这些语言中,只有当第一个参数不足以确定表达式的值时,才执行或求值第二个参数: 当 AND 函数的第一个参数求值为 false 时,整体值必须为 false;。

Not Safe 意味着操作符总是检查子句中的每个条件,因此在上面的示例中,当 x 实际上是0值时,可以计算1/x,从而引发异常。

也许知道位 AND 和位 OR 运算符总是在同一个表达式中使用条件 AND 和条件 OR 之前求值是有用的。

if ( (1>2) && (2>1) | true) // false!

如果计算涉及布尔 & 运算符的表达式,则计算两个操作数。然后将 & 运算符应用于操作数。

当计算涉及 & & 运算符的表达式时,将计算第一个操作数。如果第一个操作数的计算结果为 false,则跳过第二个操作数的计算。

If the first operand returns a value of true then the second operand is evaluated. If the second operand returns a value of true then && operator is then applied to the first and second operands.

类似于 | 和 | | 。

虽然基本的区别是,&主要用于 longintbyte上的按位操作,在这些地方它可以用作某种掩码,但即使使用它而不是逻辑 &&,结果也可能有所不同。

在某些情况下,这种差异更为明显:

  1. 计算一些表达式是很耗时的
  2. 只有当前一个表达式为 true 时,才能计算其中一个表达式
  3. 这些表达式有一些副作用(有意或无意)

第一点非常简单,它不会引起 bug,但是需要更多的时间。如果在一个条件语句中有几个不同的检查,那么将那些更便宜或更有可能失败的检查放在左边。

关于第二点,请看下面的例子:

if ((a != null) & (a.isEmpty()))

This fails for null, as evaluating the second expression produces a NullPointerException. Logical operator && is lazy, if left operand is false, the result is false no matter what right operand is.

例如第三点——假设我们有一个使用 DB 的应用程序,它没有任何触发器或级联。在删除 Building 对象之前,必须将 Department 对象的 build 更改为另一个。我们还假设操作状态作为布尔值返回(true = Success)。然后:

if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))

这会计算两个表达式,因此即使部门更新由于某种原因失败,也会执行生成删除。对于 &&,它按预期工作,并且在第一次故障后停止。

对于 a || b,它等价于 !(!a && !b),如果 a为真,它就停止,不需要更多的解释。

In Java, the single operators &, |, ^, ! depend on the operands. If both operands are ints, then a bitwise operation is performed. If both are booleans, a "logical" operation is performed.

如果两个操作数不匹配,则引发编译时错误。

双操作符 & & ,| | 的行为与单操作符类似,但两个操作数都必须是条件表达式,例如:

如((a < 0) & & (b < 0)){ ... }或类似情况, if (( a < 0 ) || ( b < 0 )) { ... }

source: java programming lang 4th ed

是逻辑运算符... 短路

是布尔逻辑运算符,非短路

转移到表达式执行的差异。不管左边的结果如何,按位运算符计算两边。但是在使用逻辑运算符计算表达式的情况下,右手表达式的计算依赖于左手条件。

For Example:

int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

这将打印 i = 26; j = 25,因为第一个条件为 false,所以忽略右手条件,因为无论如何结果为 false,与右手边条件无关。(短路)

int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

But, this will print i=26; j=26,

我知道这里有很多答案,但它们看起来都有点令人困惑。因此,在从 Java Oracle 学习指南中做了一些研究之后,我提出了三种不同的使用 & & 或 & 的场景。 这三个场景是 逻辑和按位与布尔型和

逻辑和: Logical AND (aka Conditional AND) uses the & & operator. It's short-circuited meaning: if the left operand is false, then the right operand will not be evaluated.
Example:

int x = 0;
if (false && (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); // "0"

在上面的例子中,打印到 x 控制台的值是0,因为 if 语句中的第一个操作数是 false,因此 java 不需要计算(1 = = + + x) ,因此 x 不会被计算。

按位: 按位 AND 使用 &运算符。它用来预先形成一个位操作的价值。通过观察对二进制数的运算,可以更容易地看出发生了什么,例如:

int a = 5;     //                    5 in binary is 0101
int b = 12;    //                   12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4

正如您在示例中看到的,当数字5和12的二进制表示形式排成一行时,预先编写的按位 AND 只会产生一个二进制数,其中两个数中相同的数字都有一个1。因此,0101 & 1100 = = 0100。十进制是5 & 12 = = 4。

布尔值和: 现在,布尔 AND 操作符的行为与位 AND 和逻辑 AND 相似且不同。我喜欢把它看作是在两个布尔值(或位)之间预先形成一个按位 AND,因此它使用 & 运算符。布尔值也可以是逻辑表达式的结果。

It returns either a true or false value, much like the logical AND, but unlike the logical AND it is not short-circuited. The reason being, is that for it to preform that bitwise AND, it must know the value of both left and right operands. Here's an ex:

int x = 0;
if (false & (1 == ++x) {
System.out.println("Inside of if");
}
System.out.println(x); //"1"

Now when that if statement is ran, the expression (1 == ++x) will be executed, even though the left operand is false. Hence the value printed out for x will be 1 because it got incremented.

This also applies to Logical OR (||), bitwise OR (|), and boolean OR (|) 希望这能解释清楚一些疑惑。