和&之间的区别是什么?和&&在Java?

时间:2011-04-06 09:46:55

标签: java operators boolean bitwise-operators

我一直以为Java中的&&运算符用于验证它的布尔操作数是否都是true,而&运算符用于对两个整数进行逐位运算类型。

最近我开始知道&运算符也可用于验证它的布尔操作数是否都是true,唯一的区别是它检查RHS操作数,即使LHS操作数为假。

Java中的&运算符是否内部重载?或者这背后有其他一些概念吗?

15 个答案:

答案 0 :(得分:239)

&安培; < - 验证两个操作数
&安培;&安培; < - 停止评估第一个操作数是否计算为false,因为结果将为false

(x != 0) & (1/x > 1)< - 这意味着评估(x != 0)然后评估(1/x > 1)然后执行&amp ;.问题是,对于x = 0,这将抛出异常。

(x != 0) && (1/x > 1)< - 这意味着评估(x != 0),只有当这是真的,然后评估(1/x > 1)所以如果你有x = 0那么这是非常安全的,不会抛出如果(x!= 0)的计算结果为false,则整个事物直接求值为false而不评估(1/x > 1)

编辑:

exprA | exprB< - 这意味着评估exprA然后评估exprB然后执行|

exprA || exprB< - 这意味着评估exprA,并且只有false评估exprB,然后评估||并执行{{1}}。

答案 1 :(得分:45)

除了通过评估两个操作数不是一个惰性求值器之外,我认为按位运算符的主要特征比较操作数的每个字节,如下例所示:

int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100

答案 2 :(得分:29)

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

答案 3 :(得分:10)

这取决于参数的类型......

对于整数参数,单个&符号(“&”)是“按位AND”运算符。双&符号(“&&”)没有为两个布尔参数定义任何东西。

对于布尔参数,单个&符号构成(无条件)“逻辑AND”运算符,而双&符号(“&&”)是“条件逻辑AND”运算符。也就是说单个&符号总是评估两个参数,而双符号只会在第一个参数为真时评估第二个参数。

对于所有其他参数类型和组合,应该发生编译时错误。

答案 4 :(得分:9)

&安培;&安培;是一个短路运营商,而&是一个AND运算符。

试试这个。

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false

答案 5 :(得分:7)

我认为我的回答更容易理解:

&&&之间存在两个差异。

如果他们使用逻辑AND

&&&可以是逻辑AND,当&&&左右表达式结果全部为真时,整个操作结果可以是的。

&&&为逻辑AND时,存在差异:

当使用&&作为逻辑AND时,如果左表达式结果为false,则右表达式将不会执行。

举个例子:

String str = null;

if(str!=null && !str.equals("")){  // the right expression will not execute

}

如果使用&

String str = null;

if(str!=null & !str.equals("")){  // the right expression will execute, and throw the NullPointerException 

}

另一个例子:

int x = 0;
int y = 2;
if(x==0 & ++y>2){
    System.out.print(“y=”+y);  // print is: y=3
}
int x = 0;
int y = 2;
if(x==0 && ++y>2){
    System.out.print(“y=”+y);  // print is: y=2
}

<强>&安培;可以用作位运算符

&可用作按位AND运算符,&&则不能。

  

按位AND“&amp;”当且仅当两个位都在时,运算符才产生1   它的操作数是1.但是,如果两个位都是0或两个位都不同,则此运算符产生0.更精确地按位AND“&amp;”如果两位中的任何一位为1,则运算符返回1,如果任何位为0,则返回0。

来自维基页面:

http://www.roseindia.net/java/master-java/java-bitwise-and.shtml

答案 6 :(得分:5)

它在JLS (15.22.2)

中指定
  

当&amp;,^或|的两个操作数时operator的类型为boolean或Boolean,则按位运算符表达式的类型为boolean。在所有情况下,操作数都必须根据需要进行拆箱转换(第5.1.8节)。

     

对于&amp ;,如果两个操作数值都为真,则结果值为true;否则,结果是错误的。

     

对于^,如果操作数值不同,则结果值为true;否则,结果是错误的。

     

对于|,如果两个操作数值都为false,则结果值为false;否则,结果是真的。

“技巧”是&整数位运算符以及布尔逻辑运算符。那么为什么不这样做,将此作为运算符重载的示例是合理的。

答案 7 :(得分:4)

'&amp;&amp;': - 是一个逻辑AND运算符,根据其参数的逻辑关系产生一个布尔值true或false。

例如: - Condition1&amp;&amp;条件2

如果Condition1为假,则(Condition1&amp;&amp; Condition2)将始终为false,这就是为什么此逻辑运算符也称为短路运算符的原因,因为它不评估另一个条件。如果Condition1为false,则无需评估Condtiton2。

如果Condition1为true,则计算Condition2,如果为true,则整体结果为true,否则为false。

'&amp;': - 是一个按位AND运算符。如果输入位都是1,则在输出中产生一(1)。否则它会产生零(0)。

例如: -

int a = 12; // 12的二进制表示是1100

int b = 6; // 6的二进制表示是0110

int c =(a&amp; b); //(12&amp; 6)的二进制表示是0100

c的值为4。

供参考,请参阅此http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html

答案 8 :(得分:3)

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

区别在于处理信息的场景。对于a = 0且b = 1,右表达式“(a!= 0)&amp;(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 = 1时编写表达式(a != 0) && ( b != 0),会发生以下情况:

a != 0 -->false
expression returns false

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

答案 9 :(得分:3)

&&||被称为短路运营商。使用它们时,对于|| - 如果第一个操作数计算为true,则不评估其余操作数。对于&& - 如果第一个操作数的计算结果为false,则其余部分根本不进行评估。

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

答案 10 :(得分:3)

除此之外&amp;&amp;和||在短路时,在混合两种形式时也要考虑运算符优先级。 我认为对于每个人来说,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

答案 11 :(得分:0)

&安培;是一个按位运算符加上用于检查两个条件,因为有时我们需要评估这两个条件。 但是&amp;&amp;当第一个条件给出时,逻辑运算符进入第二个条件。

答案 12 :(得分:0)

所有答案均为great,似乎no更多答案is needed 但我只是想指出一些名为&&

dependent condition运算符

在使用operator&amp;&amp;的表达式中,一个条件 - 我们称之为dependent condition - 可能需要另一个条件才能使依赖条件的评估有意义。

在这种情况下,依赖条件应放在&amp;&amp;操作员以防止错误。

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

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

另一件事:&&||被称为short-circuit evaluation因为第二个参数被执行或评估only if first参数not suffice } determine value

expression

参考文献:Java™ How To Program (Early Objects), Tenth Edition

答案 13 :(得分:0)

关于 AND 和 OR 运算符,Java 有两种类型的计算,即 Short-Circuit evaluationfull evaluation

&& || 短路评估

短路求值使您可以不求 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

注意:

  1. 请注意,对于 XOR (^) 没有短路,因为始终需要双方来确定整体结果。
  2. 请注意,短路评估的其他可能名称是 minimal evaluationMcCarthy evaluation
  3. 不建议在同一个表达式中混合布尔逻辑和动作
  4. & 还可以作为一个非常学术性的按位 AND 运算符,可用于密码学。当两个位都为 1 时,结果为 1,或其中一位不为 1,则结果为 0。(检查以下代码)

AND 按位示例:

byte a = 5;              // 00000101
byte b = 3;              // 00000011
byte c = (byte) (a & b); // 00000001 (c is 1)

答案 14 :(得分:0)

几乎所有比较点都包含在所有答案中。我只想补充一个例子。演示输出如何根据我们使用的运算符而变化。考虑下面的例子

int a = 10;
if(++a==10 & ++a==12) {
    ++a;
}
System.out.println(a); //12

在上面的代码中,我们使用了按位 & 运算符。因此,无论单个结果如何,它都会评估两个参数(左和右)。

所以 a 将在 if condition 内增加 2 倍。但由于条件不会变为真,它不会进入 if 循环内部,也不会发生第三次增量。因此,在这种情况下,a 的最终值将变为 12。

现在假设,在上面的同一个例子中,如果我们使用短路&&运算符。然后在评估 ++a==10 为假之后,它不会去检查第二个参数。因此最终值可能是 11。

int a = 10;
if(++a==10 && ++a==12) {
    ++a;
}
System.out.println(a); //11

基于此,我们可以说与短路&&运算符相比,按位&运算符的性能相对较低。由于按位运算符将评估两个参数,而不管第一个参数的结果如何。如果第一个参数的结果为假, && 运算符将停止评估第二个参数。

这两者之间的另一个区别是,按位 & 运算符适用于布尔类型和整数类型。而短路 && 运算符仅适用于布尔类型。

我们可以写

System.out.println(4 & 5); // 4

但是如果我们试着写成这样,

System.out.println(4 && 5);

然后它会给出一个错误说,

<块引用>

二元运算符“&&”的错误操作数类型