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

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

这些是按位与和运算符。

 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 )中关于操作符根据其input的不同行为的适当部分。

实际上,当两个input都是布尔值时,运算符被认为是布尔逻辑运算符,其行为类似于条件运算符( && )和条件运算符( || ),除了它们不会短路以下是安全的:

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

这不是:

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

我想你在谈论这两个运营商的逻辑意义,在这里你有一个表简历:

 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 

我知道这里有很多答案,但他们似乎有点混乱。 因此,在从Java的oracle学习指南做了一些研究之后,我想出了三种不同的时间来使用&&或者&。 这三种情况是逻辑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的二进制表示排列在一起时,那么按位“与”执行的操作将只会生成一个二进制数,其中两个数字中的相同数字都有一个1.因此,0101&1100 == 0100.小数点是5&12 == 4。

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

它返回一个真或假的值,就像逻辑AND一样,但与逻辑AND不同,它不会被短路。 原因在于,它要预先执行按位AND操作,它必须知道左侧和右侧操作数的值。 这里是一个例子:

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

现在,当if语句运行时,即使左操作数为假,expression式(1 == ++ x)也会被执行。 因此,为x打印出的值将为1,因为它已经增加。

这也适用于逻辑OR(||),按位OR(|)和布尔OR(|)希望这清除了一些混淆。

运算符&&和|| 是短路的,这意味着如果左侧expression式的值足以确定结果,则它们将不评估它们的右侧expression式。

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

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

&&|| 只对布尔运算(和其他的回答已经说过,短路)。

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

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

双运算符&&,|| 行为类似于单个对象,但是两个操作数都必须是条件expression式,例如:

((a <0)&&(b <0)){…}或类似地,如果((a <0)||(b <0)){…}

源代码:java编程lang 4th ed

也许有必要知道在相同expression式的条件AND和条件OR之前总是评估按位“与”运算符和按位OR运算符。

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

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

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

转向expression式执行上的差异。 按位运算符评估双方,而不考虑左手的结果。 但是在用逻辑运算符评估expression式的情况下,右手expression式的评估取决于左手的条件。

例如:

 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,由于第一个条件是错误的,所以不pipe右手边的条件如何,右边的条件被忽略了,结果是错误的(短路)

 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,

如果涉及布尔操作符的expression式被评估,则两个操作数都被评估。 然后将&运算符应用于操作数。

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

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

类似于| 和||。

虽然基本的区别在于,用于按位操作的操作主要是longint或者byte ,它们可以用作掩码types,但即使使用它而不是逻辑&& ,结果也可能不同。

在一些情况下差异更明显:

  1. 评估一些expression式是耗时的
  2. 只有当前一个是真的时,才能评估其中一个expression式
  3. expression式有一些副作用(有意或无意)

第一点非常简单,不会造成任何错误,但需要更多的时间。 如果在一个条件语句中有几个不同的检查,那么把那些更便宜或更可能失败的条件放在左边。

第二点,请看这个例子:

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

这将失败为null ,因为评估第二个expression式会产生NullPointerException 。 逻辑运算符&&是懒惰的,如果左操作数为假,那么无论右操作数是多less,结果都是假的。

第三点的例子 – 比方说,我们有一个应用程序,使用DB没有任何触发器或级联。 在删除Building对象之前,我们必须将一个Department对象的build筑物更改为另一个。 我们还要说操作状态是以布尔值(true = success)的forms返回的。 然后:

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

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

至于a || b a || b ,它相当于!(!a && !b) ,如果a为真,则停止,不需要更多解释。