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

Differences in boolean operators: & vs && and | vs ||

提问人:Sumithra 提问时间:10/25/2010 最后编辑:MachavitySumithra 更新时间:11/6/2020 访问量:226095

问:

我知道 和 的规则,但 和 是什么?请用一个例子向我解释这些。&&||&|

java 按位 逻辑运算符 boolean-logic

评论

0赞 JavaGeek 9/22/2021
看到这个帖子的一个很好的解释:stackoverflow.com/questions/7101992/......

答:

157赞 Justin Niessner 10/25/2010 #1

这些是按位 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

感谢 Carlos 指出 Java 语言规范(15.22.1、15.22.2)中关于运算符根据其输入的不同行为的相应部分。

事实上,当两个输入都是布尔值时,运算符被视为布尔逻辑运算符,其行为类似于 Conditional-And () 和 Conditional-Or () 运算符,只是它们不会短路,因此以下操作是安全的:&&||

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

这不是:

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

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

运算符总是检查子句中的每个条件,因此在上面的示例中,当实际上是一个值时,可能会计算,从而引发异常。&a.somethinganull

评论

1赞 gideon 10/25/2010
想澄清一下..& 仅当 BOTH 为 1 时才会返回 1?所以 101 和 001 会是 001 吗?右?
0赞 Justin Niessner 10/25/2010
@giddy @Jonathon - 我更新了我的值以更好地显示这种情况。
1赞 user85421 10/25/2010
不完全:它们也是 LOGICAL 运算符(用于布尔值)。
1赞 Justin Niessner 10/25/2010
@Carlos-没有。它们仍然是按位运算符。它们的行为与非短路逻辑运算符相同。这是有区别的。
4赞 user85421 10/26/2010
什么是非短路逻辑算子?运算符 & 和 |(由 OP 询问)是“整数按位运算符”(JLS 15.22.1)“布尔逻辑运算符”(JLS 15.22.2)。还是 Java 语言规范对此有误?
7赞 Tassos Bassoukos 10/25/2010 #2

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

评论

8赞 Alnitak 10/25/2010
-1 告诉 OP 他已经知道的事情,而不是回答他实际提出的问题。
1赞 Bruno 10/25/2010 #3

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

&&并且仅在布尔值上运行(并且短路,正如其他答案已经说过的那样)。||

评论

3赞 user207421 9/26/2016
&并且也是布尔类型的布尔运算符。|
5赞 Brian Scott 10/25/2010 #4

& 和 |提供与 && 和 || 相同的结果运营商。不同之处在于,它们总是计算表达式的两端,其中 as && 和 ||停止评估第一个条件是否足以确定结果。

评论

1赞 Buhake Sindi 10/25/2010
错。。。。因为它评估这两个结果,而仅当第一个条件为真时才返回。&&||
1赞 Brian Scott 10/25/2010
哼?&& 仅当表达式的右侧已计算结果为 true 时,才计算表达式的右侧。否则,它将停止计算,因为第一个 false 隐含意味着结果不可能是真的。查看 jguru.com/faq/view.jsp?EID=16530
1赞 Piskvor left the building 10/25/2010
( 2 & 4 )计算结果为 ,而计算结果为 。结果到底是怎么回事?false( 2 && 4 )true
1赞 user85421 10/26/2010
@Piskvor - 不是在 Java 中! 结果为整数,而不是布尔值(在本例中为零)。 不会编译,&&只接受布尔值。Java 不允许混合使用布尔值和整数:零不是,不是零......2 & 42 && 4falsefalse
1赞 user207421 9/26/2016
@BuhakeSindi错了。因为它只计算第二个操作数,如果第一个操作数是 。&&true
116赞 Torres 10/25/2010 #5

我想你说的是两个运算符的逻辑含义,这里你有一个表简历:

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

短路求值、最小求值或麦卡锡求值(在 John McCarthy 之后)是某些编程语言中某些布尔运算符的语义,其中仅当第一个参数不足以确定表达式的值时,才会执行或计算第二个参数:当 AND 函数的第一个参数计算结果为 false 时, 总体值必须为 false;当 OR 函数的第一个参数的计算结果为 true 时,总值必须为 true。

“不安全”意味着运算符始终检查子句中的每个条件,因此在上面的示例中,当 x 实际上是 0 值时,可能会计算 1/x,从而引发异常。

评论

1赞 tim-montague 11/4/2017
@Torres - 请通过解释“短路”和“安全”来扩展您的答案。“排他性或”和“逻辑性不”是否也是“不短路”?为什么它被称为“逻辑不”而不是“布尔逻辑不”?为什么“逻辑 NOT”不与“逻辑 AND”和“逻辑 OR”组合在一起?很好的答案,但需要工作。
0赞 Taslim Oseni 12/17/2017
@tfmontague,我已经解释了短路的含义(通过编辑这个答案)。等待我的编辑被“同行评审”。
0赞 SCI 6/7/2018
不短路有什么“不安全”?难道不应该比使用短路更安全吗?顺便说一句:你并没有真正解释“短路”这个词。这意味着在“不短路”时,首先计算所有部件,然后应用布尔运算,而在短路时,计算停止,当第一个表达式满足条件时,例如(a || b)不会计算b,如果a为真,则OR操作将返回true,无论b是什么。
1赞 alexmeia 9/4/2013 #6

也许知道按位 AND 和按位 OR 运算符总是在条件 AND 和条件 OR 用于同一表达式之前计算会很有用。

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

评论

1赞 John Dvorak 9/4/2013
您的意思是操作员优先级而不是评估顺序吗?我宁愿不看到实际代码中使用的优先级差异。为此,请使用括号而不是按位运算符。
0赞 RishiKesh Pathak 12/3/2014 #7

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

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

如果第一个操作数返回值 true,则计算第二个操作数。如果第二个操作数返回值 true,则 & 运算符将应用于第一个和第二个操作数。

与 |和 ||。

0赞 Vlasec 12/9/2014 #8

虽然基本区别在于主要用于 上的按位运算,或者它可以用于掩码,但即使您使用它而不是逻辑 ,结果也可能有所不同。&longintbyte&&

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

  1. 计算某些表达式非常耗时
  2. 仅当前一个表达式为真时,才能计算其中一个表达式
  3. 这些表达式有一些副作用(有意或无意)

第一点很简单,它不会导致错误,但需要更多时间。如果在一个条件语句中有多个不同的检查,请将那些更便宜或更有可能失败的检查放在左侧。

第二点,请看这个例子:

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

这对于 失败,因为计算第二个表达式会产生 .逻辑运算符是懒惰的,如果左操作数为假,则无论右操作数是什么,结果都是假的。nullNullPointerException&&

第三点的例子 -- 假设我们有一个应用程序,它使用没有任何触发器或级联的数据库。在删除 Building 对象之前,必须将 Department 对象的建筑物更改为另一个建筑物。我们还假设操作状态以布尔值的形式返回(true = 成功)。然后:

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

这将评估这两个表达式,因此即使部门更新由于某种原因失败,也会执行建筑物移除。使用 ,它会按预期工作,并在第一次失败后停止。&&

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

3赞 aaron p. 3/5/2015 #9

在 Java 中,单运算符 &, |, ^, !取决于操作数。如果两个操作数都是 ints,则执行按位运算。如果两者都是布尔值,则执行“逻辑”运算。

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

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

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

来源:Java Programming Lang 第 4 版

1赞 Nickhil 6/16/2015 #10

&& ; ||是逻辑运算符......短路

& ; |是布尔逻辑运算符......非短路

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

例如:

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,由于第一个条件是假的,所以右手条件被绕过,因为无论如何结果都是假的,而不管右手条件如何。(短路)

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=26,

32赞 LynchburgExplorer 4/9/2016 #11

我知道这里有很多答案,但它们似乎都有点令人困惑。因此,在对 Java 预言机学习指南进行了一些研究之后,我提出了三种不同的场景来说明何时使用 && 或 &。 这三种方案是逻辑 AND按位 ANDY布尔 AND

逻辑 AND:逻辑 AND(又名条件 AND)使用 && 运算符。这是短路的意思:如果左操作数为假,则不会计算右操作数。
例:

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:按位 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,因此它使用 & 运算符。布尔值也可以是逻辑表达式的结果。

它返回一个 true 或 false 值,与逻辑 AND 非常相似,但与逻辑 AND 不同,它不会短路。原因是,为了让它预置按位 AND,它必须知道左操作数和右操作数的值。这里有一个前任:

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

现在,当运行 if 语句时,将执行表达式 (1 == ++x),即使左操作数为 false。因此,为 x 打印出的值将为 1,因为它已递增。

这也适用于逻辑 OR (||)、按位 OR (|) 和布尔 OR (|) 希望这能消除一些困惑。

评论

0赞 Koray Tugay 2/4/2018
to preform that bitwise AND, it must know the value of both left and right operands这对我来说听起来不对。要执行 ,如果左操作数是 ,则无需知道正确的操作数即可计算出结果。你的解释是正确的,但你陈述的推理似乎并非如此,至少在我看来是这样。BITWISE ANDFALSE