我知道&&
和||
的规则,但&
和|
是什么?请以一个例子向我解释这些。
答案 0 :(得分:122)
这些是按位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)中指出了基于其输入的运营商的不同行为。
实际上,当两个输入都是布尔值时,运算符被认为是布尔逻辑运算符,其行为类似于条件 - 和(&&
)和条件 - 或(||
)运算符,除了事实他们不会短路,所以以下是安全的:
if((a != null) && (a.something == 3)){
}
这不是:
if((a != null) & (a.something == 3)){
}
“短路”意味着操作员不一定检查所有条件。在上面的例子中,&&
仅在a
不是null
时检查第二个条件(否则整个语句将返回false,无论如何都要检查以下条件),所以a.something
的陈述不会引起异常,或者被认为是“安全的”。
&
运算符始终检查子句中的每个条件,因此在上面的示例中,当a.something
实际上是a
值时,null
可能会被评估一个例外。
答案 1 :(得分:101)
我认为你在谈论两个运营商的逻辑意义,在这里你有一个表简历:
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
答案 2 :(得分:23)
我知道这里有很多答案,但它们看起来有点令人困惑。所以在从Java oracle学习指南做了一些研究后,我想出了三个不同的场景,即何时使用&& amp;或者&amp ;. 这三种情况是逻辑AND ,按位AND ,布尔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的行为相似且不同。我喜欢把它想象为在两个布尔值(或位)之间执行按位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语句时,即使左操作数为false,也会执行表达式(1 == ++ x)。因此,为x打印的值将为1,因为它会增加。
这也适用于逻辑OR(||),按位OR(|)和布尔OR(|) 希望这可以解决一些困惑。
答案 3 :(得分:7)
运营商&&和||是短路的,这意味着如果左手表达式的值足以确定结果,他们就不会评估他们的右手表达。
答案 4 :(得分:5)
&安培;和|提供与&& amp;相同的结果和||运营商。不同之处在于,他们总是评估表达式的两侧,其中&&和||停止评估第一个条件是否足以确定结果。
答案 5 :(得分:2)
在Java中,单个运算符&,|,^ ,!取决于操作数。如果两个操作数都是整数,则执行按位运算。如果两者都是布尔值,则执行“逻辑”操作。
如果两个操作数不匹配,则抛出编译时错误。
双重算子&&,||行为类似于单个对应物,但两个操作数必须是条件表达式,例如:
if((&lt; 0)&amp;&amp;(b&lt; 0)){...}或类似地, if((&lt; 0)||(b <0)){...}
source:java programming lang 4th ed
答案 6 :(得分:1)
&
和|
是整数类型的按位运算符(例如int
):http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
&&
和||
仅对布尔值进行操作(并且短路,正如其他答案已经说过的那样)。
答案 7 :(得分:1)
也许知道在条件AND和条件OR在同一个表达式中使用之前总是评估按位AND和按位OR运算符。
if ( (1>2) && (2>1) | true) // false!
答案 8 :(得分:1)
&安培;&安培; ; ||是逻辑运算符....短路
&安培; ; |是布尔逻辑运算符....非短路
转向表达式执行的差异。无论左侧的结果如何,按位运算符都会评估双方。但是在使用逻辑运算符计算表达式的情况下,右手表达式的评估取决于左手条件。
例如:
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,
答案 9 :(得分:0)
如果计算涉及布尔&amp; 运算符的表达式,则会计算两个操作数。然后&amp;运算符应用于操作数。
当评估涉及&amp;&amp; 运算符的表达式时,将计算第一个操作数。如果第一个操作数的计算结果为false,则跳过第二个操作数的计算。
如果第一个操作数返回值true,则计算第二个操作数。如果第二个操作数返回值true,则&amp;&amp;然后将运算符应用于第一个和第二个操作数。
类似于|和||。
答案 10 :(得分:0)
虽然基本区别在于,&
主要用于long
,int
或byte
的按位操作,其中它可用于掩码类型,即使您使用它而不是逻辑&&
,结果也会有所不同。
在某些情况下,差异更明显:
第一点非常简单,它不会导致错误,但需要更多时间。如果你在一个条件语句中有几个不同的检查,那么将那些更便宜或更有可能失败的检查放在左边。
对于第二点,请参阅此示例:
if ((a != null) & (a.isEmpty()))
null
失败,因为评估第二个表达式会产生NullPointerException
。逻辑运算符&&
是惰性的,如果左操作数为假,则无论右操作数是什么,结果都是假的。
第三点的示例 - 让我们说我们有一个使用DB而没有任何触发器或级联的应用程序。在我们删除Building对象之前,我们必须将Department对象的构建更改为另一个。我们还说操作状态作为布尔值返回(true =成功)。然后:
if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))
这会评估两个表达式,从而即使部门更新由于某种原因失败也会执行构建删除。对于&&
,它按预期工作,并在首次失败后停止。
对于a || b
,它等同于!(!a && !b)
,如果a
为真,则停止,不再需要解释。