Java logical operator short-circuiting

Which set is short-circuiting, and what exactly does it mean that the complex conditional expression is short-circuiting?

public static void main(String[] args) {
int x, y, z;


x = 10;
y = 20;
z = 30;


// T T
// T F
// F T
// F F


//SET A
boolean a = (x < z) && (x == x);
boolean b = (x < z) && (x == z);
boolean c = (x == z) && (x < z);
boolean d = (x == z) && (x > z);
//SET B
boolean aa = (x < z) & (x == x);
boolean bb = (x < z) & (x == z);
boolean cc = (x == z) & (x < z);
boolean dd = (x == z) & (x > z);


}
165378 次浏览

SET A 使用短路布尔运算符。

在布尔运算符的上下文中,“短路”的意思是,对于一组布尔值 b1,b2,... ,bn,当第一个布尔值为 true (| |)或 false (& &)时,短路版本将停止计算。

例如:

// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)


// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)

&&||操作员“短路”,这意味着如果没有必要,他们不会评估右侧。

&|运算符用作逻辑运算符时,总是计算两边。

每个操作员只有一个短路的情况,它们是:

  • 不需要知道右边是什么,因为不管右边的值是什么,结果都只能是 false
  • 不需要知道右边是什么,因为不管右边的值是什么,结果都只能是 true

让我们用一个简单的例子来比较这种行为:

public boolean longerThan(String input, int length) {
return input != null && input.length() > length;
}


public boolean longerThan(String input, int length) {
return input != null & input.length() > length;
}

第二个版本使用非短路操作符 &,如果 inputnull,则抛出 NullPointerException,但第一个版本将毫无例外地返回 false

简单地说,短路意味着一旦你知道答案不能再改变,就停止求值。例如,如果您正在计算一个逻辑 AND链,并且您在该链的中间发现了一个 FALSE,那么您知道结果将是 false,无论该链中其余表达式的值是什么。对于 OR链也是如此: 一旦你发现了 TRUE,你马上就知道了答案,所以你可以跳过计算其余的表达式。

通过使用 &&而不是 &||而不是 |,您可以向 Java 表明希望进行短路。你文章中的第一组是短路。

请注意,这不仅仅是为了节省一些 CPU 周期: 在这样的表达式中

if (mystring != null && mystring.indexOf('+') > 0) {
...
}

Short-Circuit iting 意味着正确操作和崩溃之间的区别(在 mystring 为 null 的情况下)。

boolean a = (x < z) && (x == x);

这种方法会发生短路,也就是说如果 (x < z)的计算结果为 false,那么后者就不会被计算,a也会被计算为 false,否则 &&也会被计算为 (x == x)

&是位运算符,但也是不短路的布尔 AND 运算符。

您可以通过以下方法来测试它们(请看在每种情况下调用该方法的次数) :

public static boolean getFalse() {
System.out.println("Method");
return false;
}


public static void main(String[] args) {
if(getFalse() && getFalse()) { }
System.out.println("=============================");
if(getFalse() & getFalse()) { }
}

短路意味着如果第一个操作者决定最终结果,第二个操作者将不会被检查。

表达式是: 真 | 假

在这种情况下,我们只需要 其中一边是真实的。因此,如果左边为真,那么检查右边就没有意义了,因此根本不会检查右边。

Similarly, False && True

在 & & 的情况下,我们需要 双方为真。因此,如果左边是 False,那么检查右边就没有意义了,答案必须是 False。因此,它根本不会被检查。

if(demon!=0&& num/demon>10)

因为使用了 AND (& &)的短路形式,所以当时间为零时不会产生运行时异常的风险。

参考文献 Java2第五版作者: Herbert Schilt

Java 提供了两个有趣的布尔运算符,这在大多数其他计算机语言中是找不到的。AND 和 OR 的这些次要版本称为 short-circuit logical operators。从前面的表中可以看到,当 A 为 true 时,OR 操作符的结果为 true,而不管 B 是什么。

类似地,当 A 为 false 时,AND 操作符将导致 false,无论 B 是什么。如果您使用的是 ||&&表单,而不是这些操作符的 |&表单,那么 Java 就不会仅仅计算右边的操作数。当右边的操作数依赖于左边的操作数是 true 还是 false 来正常运行时,这非常有用。

例如,下面的代码片段显示了如何利用短路逻辑计算来确保除法运算在计算之前是有效的:

if ( denom != 0 && num / denom >10)

由于使用了 AND (&&)的短路形式,因此不存在因除以零而导致运行时异常的风险。如果这行代码是使用单个 &版本的 AND 编写的,那么两边都必须进行计算,当 denom为零时会导致运行时异常。

在涉及布尔逻辑的情况下使用 AND 和 OR 的短路形式是标准实践,将单字符版本专门留给按位操作。然而,这个规则也有例外。例如,考虑以下陈述:

 if ( c==1 & e++ < 100 ) d = 100;

Here, using a single & ensures that the increment operation will be applied to e whether c is equal to 1 or not.

如果至少有一个操作数的值为 true,则逻辑 OR:-返回 true。在应用 OR 运算符之前,对两个操作数都进行计算。

Short Circuit OR :- if left hand side operand returns true, it returns true without evaluating the right hand side operand.

&&&运算符之间有一些不同之处。同样的差异也适用于 |||。需要记住的最重要的一点是,&&是一个仅适用于布尔操作数的 logical操作符,而 &是一个既适用于布尔值又适用于整数类型的 bitwise操作符。

使用逻辑运算,您可以进行短路,因为在某些情况下(比如 &&的第一个操作数是 false,或者 ||的第一个操作数是 true) ,您不需要计算表达式的其余部分。这对于在访问文件或方法之前检查 null,以及在用零除以它们之前检查潜在零之类的事情非常有用。对于复杂表达式,表达式的每个部分都以相同的方式递归求值。例如,在下列情况下:

(7 == 8) || ((1 == 3) && (4 == 4))

只有被强调的部分才会被评估。要计算 ||,首先检查 7 == 8是否为 true。如果是的话,右手边就会被完全跳过。右边只检查 1 == 3是否为 false。因为它是,所以不需要检查 4 == 4,并且整个表达式的计算结果为 false。如果左手边是 true,例如 7 == 7而不是 7 == 8,整个右手边将被跳过,因为整个 ||表达将是 true

对于一个位操作,你需要计算所有的操作数,因为你实际上只是在组合这些比特。在 Java 中,布尔值实际上是一个一位整数(不管内部函数是如何工作的) ,在这种特殊情况下,您可以对位运算符进行短路只是一种巧合。不能短路一般整数 &|操作的原因是,在任何一个操作数中,有些位可能是打开的,有些位可能是关闭的。像 1 & 2这样的东西得到的结果是零,但是如果不计算这两个操作数,您就无法知道这个结果。

Docs.oracle 的文件

由于逻辑表达式是从左到右计算的,因此要使用以下规则测试它们是否可能存在“短路”计算:

任何东西都被短路评估为假。

任何东西都会短路。

逻辑规则保证这些评价总是正确的。请注意,上述表达式的任何部分都没有计算,因此这样做的任何副作用都不会生效。

Https://docs.oracle.com/cd/e57185_01/hirug/ch31s05s01.html