&和&&之间的区别

156 java boolean operators bitwise-operators

我一直认为&&Java 中的运算符用于验证它的布尔操作数是否都是true,并且&运算符用于对两个整数类型执行逐位运算.

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

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

ITr*_*ubs 254

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

(x != 0) & (1/x > 1)< - 这意味着评估(x != 0)然后评估(1/x > 1)然后做&.问题是,对于x = 0,这将引发异常.

(x != 0) && (1/x > 1)< - 这意味着评估(x != 0)并且只有当这是真的然后评估(1/x > 1)所以如果你有x = 0那么这是非常安全的并且如果(x!= 0)评估为false则不会抛出任何异常,整个事物直接评估为假没有评估(1/x > 1).

编辑:

exprA | exprB< - 这意味着评估exprA然后评估exprB然后做|.

exprA || exprB< -这意味着评估exprA且仅当这false则评估exprB并执行||.

  • @ Michu93:一个例子是如果第二个条件是一个函数调用,它具有你总是需要的副作用.由于通常应该避免副作用,因此只有极少数情况下你需要它,我现在想不出一个现实的例子. (12认同)
  • 写一个&或|的原因是什么 在if声明中?它永远不会比&&和||更快.如果我们已经有答案,为什么我们要检查第二个条件?你能提供实际的例子吗? (7认同)
  • @PetrDvořák 很棒的例子。除此之外,我已经在身份验证/登录代码(包括 Spring Security)中看到了这种实现,其中无效用户名的代码执行时间应该与无效密码的代码执行时间一样长(即,前者不应短路) 。 (6认同)
  • @Michu93在实现与安全相关的代码(尤其是密码学)时,使用这些运算符可以防止基于时间测量的旁道攻击(不同结果的执行时间不同)。有时,“恒定时间”比较比“更快”比较更有价值。 (4认同)

sua*_*uat 49

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

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
Run Code Online (Sandbox Code Playgroud)

  • @EJP它仍然帮助像我这样只读标题的googlers. (21认同)
  • 问题是关于逻辑布尔运算,而不是按位运算。 (2认同)

Tor*_*res 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
Run Code Online (Sandbox Code Playgroud)


dev*_*per 10

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

对于整数参数,单个&符号("&")是"按位AND"运算符.除了两个布尔参数之外,没有为任何东西定义双符号("&&").

对于布尔参数,单个&符号构成(无条件)"逻辑AND"运算符,而双&符号("&&")构成"条件逻辑AND"运算符.也就是说单个&符号总是计算两个参数,而双&符号仅在第一个参数为真时才计算第二个参数.

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


Pri*_*ley 9

&&是短路运算符,而&是AND运算符.

试试这个.

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false
Run Code Online (Sandbox Code Playgroud)


air*_*aft 7

我想我的答案可以更容易理解:

&和之间有两个不同之处 &&.

如果他们使用逻辑AND

&并且&&可以是逻辑的AND,当&&&左右表达式结果都为真时,整个运算结果可以为真.

什么时候&&&合乎逻辑的AND,有区别:

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

举个例子:

String str = null;

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

}
Run Code Online (Sandbox Code Playgroud)

如果使用&:

String str = null;

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

}
Run Code Online (Sandbox Code Playgroud)

另一个例子:

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

&可以用作位运算符

&可以用作Bitwise AND运算符, &&不能.

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

来自维基页面:

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


And*_*s_D 6

它是在JLS(15.22.2)中指定的:

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

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

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

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

该"绝招"是,&是一个整数位运算符,以及一个布尔逻辑运算符.那么为什么不这样,将此视为运算符重载的一个例子是合理的.


小智 5

'&&' : - 是一个逻辑与运算符,根据其参数的逻辑关系产生真或假的布尔值。

例如: - 条件 1 && 条件 2

如果 Condition1 为假,则 (Condition1 && Condition2) 将始终为假,这就是该逻辑运算符也称为短路运算符的原因,因为它不评估其他条件。如果 Condition1 为 false ,则无需评估 Condtiton2。

如果 Condition1 为真,则对 Condition2 求值,如果为真,则总体结果为真,否则为假。

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

例如:-

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

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

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

c 的值为 4。

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