我为什么要经常使用|| 而不是| 和&&代替&?

Dog*_*Dog 5 java boolean bit-manipulation operators conditional-statements

自从我开始编写Java以来​​,我注意到每个人都在使用&&||不是&|.这是什么原因?我一直在使用&&,||因为我不知道你可以使用&|布尔.

class A{static{
  boolean t = true;
  boolean f = false;
  System.out.println("&ff " + (f&&f) + " " + (f&f));
  System.out.println("&ft " + (f&&t) + " " + (f&t));
  System.out.println("&tf " + (t&&f) + " " + (t&f));
  System.out.println("&tt " + (t&&t) + " " + (t&t));
  System.out.println("|ff " + (f||f) + " " + (f|f));
  System.out.println("|ft " + (f||t) + " " + (f|t));
  System.out.println("|tf " + (t||f) + " " + (t|f));
  System.out.println("|tt " + (t||t) + " " + (t|t));
}}
Run Code Online (Sandbox Code Playgroud)

据我所知,他们是一样的:

$ javac A.java && java A
&ff false false
&ft false false
&tf false false
&tt true true
|ff false false
|ft true true
|tf true true
|tt true true
Exception in thread "main" java.lang.NoSuchMethodError: main
Run Code Online (Sandbox Code Playgroud)

是否以任何方式使用||&&改进我的代码?


作为一个简单的测试,我用短格式替换了数百次,并且我的所有单元测试仍然通过.

Hab*_*bib 12

||&&使用短路评估

来自同一篇文章

短路评估,最小评估或麦卡锡评估表示某些编程语言中某些布尔运算符的语义,其中第二个参数仅在第一个参数不足以确定表达式的值时执行或计算

假设您有一个对象,并且如果您执行以下操作,则需要检查其中一个属性的某些值:

if(obj != null & obj.ID == 1)
Run Code Online (Sandbox Code Playgroud)

如果您的对象obj为null,您将获得一个空引用异常,因为您使用了单个&,第一个条件求值false,但它仍将继续到下一个条件并引发空引用异常.

如果你使用&&那么第二个条件将永远不会被评估,因此没有例外.

if(obj != null && obj.ID == 1)
Run Code Online (Sandbox Code Playgroud)

使用您的代码,您将看不到任何差异,但使用按位|&多个条件将导致完全没有短路.

更多解释.


考虑你下面的代码:

Boolean conditionA = 2 > 1; //some condition which returns true
if(conditionA | obj.SomeTimeConsumingMethod()){

}
Run Code Online (Sandbox Code Playgroud)

现在,在上面的代码段中,假设有一个方法的对象SomeTimeConsumingMethod,其取入处理,返回大量的时间truefalse.如果你使用单|会评估双方的条件,因为首先conditionAtrue它将处理obj.SomeTimeConsumingMethod为好.自从(OR)使用以来,最终结果将是true整个if语句.|

如果您的条件是使用double || (OR逻辑运算符)

if(conditionA || obj.SomeTimeConsumingMethod())
Run Code Online (Sandbox Code Playgroud)

然后obj.SomeTimeConsumingMethod()将不评估第二个条件.这是短路的,这使您无法执行一些耗时的方法.true无论从哪里返回,最终的结果仍然是obj.SomeTimeConsumingMethod().

  • +1但如果您可以添加几行或解释它会很棒! (2认同)
  • @Dog你想在> 99%的用例中使用短路语义,因此条件运算符是一个自然的默认值.普通布尔运算符的使用通常表示缺乏经验,并且很少有特定要求的良好动机. (2认同)

Pat*_*han 3

正如已经指出的,&&||做短路评估。&|,对于布尔操作数,执行相同的操作,但计算两个操作数,而不管第一个操作数的值。

在某些情况下,使用哪种操作数很重要,例如当左操作数是右操作数无异常求值的先决条件时。

大多数情况下,这并不重要。在这些情况下,我使用&&and 是||为了提高可读性,因为这是更常见的选择。将&or|与布尔操作数一起使用往往会让大多数 Java 程序员不得不停下来思考,并问自己是否有某些特定的原因。我怀疑它如此普遍可能是因为继承了 C 和 C++。