Java logical operator short-circuiting
哪一个集合是短路的,而复杂的条件表达式是短路的确切意思是什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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); } |
当用作逻辑运算符时,
每个操作员只有一种短路情况,它们是:
false && ... —不需要知道右手边是什么,结果必须是false 。true || ... —不需要知道右手边是什么,结果必须是true 。
让我们在一个简单的例子中比较一下行为:
1 2 3 4 5 6 7 |
第二个版本使用非短路运算符
集合A使用短路布尔运算符。
"短路"在布尔运算符上下文中的含义是,对于一组布尔值b1、b2、…、bn,一旦这些布尔值中的第一个为真()或假(&;&;)时,短路版本将立即停止计算。
例如:
1 2 3 4 5 6 7 | // 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) |
短路意味着如果第一个运算符决定最终结果,则不会检查第二个运算符。
例如,表达式为:真假
在的情况下,我们只需要其中一个方面是正确的。因此,如果左手边是真的,那么检查右手边就没有意义了,因此这一点也不会被检查。
同样,错误和正确
在这种情况下,我们需要双方都是真实的。因此,如果左手边是错误的,那么检查右手边就没有意义了,答案必须是错误的。因此,这将不会被检查。
1 | boolean a = (x < z) && (x == x); |
这类会短路,即如果
您可以通过以下方法对它们进行测试(查看在每种情况下调用该方法的次数):
1 2 3 4 5 6 7 8 9 10 |
简而言之,短路意味着一旦你知道答案不再改变,就停止评估。例如,如果您正在评估逻辑
通过使用EDCOX1,0,而不是EDCOX1,2,EDCX1,1,而不是EDCOX1,3,则指示Java需要短路。你发帖的第一组是短路。
注意,这不仅仅是为了节省几个CPU周期:在这样的表达式中
1 2 3 | if (mystring != null && mystring.indexOf('+') > 0) { ... } |
短路意味着正确操作和崩溃之间的区别(在mystring为空的情况下)。
通过逻辑运算,可以进行短路,因为在某些情况下(如EDOCX1的第一个操作数〔1〕是
1 | (7 == 8) || ((1 == 3) && (4 == 4)) |
只评估强调部分。要计算
对于逐位运算,您需要计算所有操作数,因为您实际上只是在组合这些位。布尔值实际上是Java中的一位整数(不管内部机制是如何工作的),在这种特殊情况下,你可以为位运算符做短路。不能短路一般整数
逻辑或:-如果至少有一个操作数的计算结果为true,则返回true。两个操作数在应用或运算符之前都要进行计算。
短路或:-如果左侧操作数返回真,则返回真而不计算右侧操作数。
Java提供了两种在大多数其他计算机语言中没有发现的有趣的布尔运算。这些和和或的辅助版本称为短路逻辑运算符。从上表中可以看到,当a为真时,无论b是什么,or运算符都会产生true。
同样,当a为false时,与运算符会导致false,无论b是什么。如果使用EDCOX1、0、EDCX1、1种形式,而不是EDCOX1、2、EDCX1和3种形式的这些运算符,Java就不会费心单独评估右操作数。当右操作数依赖于左操作数为真或假以正常工作时,这非常有用。
例如,下面的代码片段显示了如何利用短路逻辑评估,以确保在评估除法运算之前除法运算是有效的:
1 | if ( denom != 0 && num / denom >10) |
由于使用了and(
在涉及布尔逻辑的情况下,使用AND和OR的短路形式是标准实践,而将单字符版本只用于位操作。但是,这个规则也有例外。例如,考虑以下语句:
1 | if ( c==1 & e++ < 100 ) d = 100; |
这里,使用单个
1 | if(demon!=0&& num/demon>10) |
由于使用了和(&;&;)的短路形式,因此当DEMON为零时,不存在导致运行时异常的风险。
Herbert Schildt JAVA 2版第五版