Java逻辑运算符短路
哪一组是短路的,究竟是什么意思,复杂的条件expression式是短路?
public static void main(String[] args) { int x, y, z; x = 10; y = 20; z = 30; // TT // TF // FT // FF //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 || ...
– 没有必要知道右边是什么,结果必须是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; }
第二个版本使用非短路运算符&
,如果input
为null
,则会抛出一个NullPointerException
exception,但是第一个版本将返回false
而没有exception;
SET A使用短路布尔运算符。
在布尔运算符中,“短路”意味着对于一组布尔值b1,b2,…,bn,只要第一个布尔值为真,短路版本就会停止计算。 )或假(&&)。
例如:
// 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)
短路意味着第二个操作员将不会被检查,如果第一个操作员决定最终的结果。
例如Expression是:True || 假
在||的情况下,我们所需要的是一边是真的。 所以如果左边是真实的,检查右边是没有意义的,所以根本不会被检查。
同样,假&&真实
在&&的情况下,我们需要双方都是真的。 所以如果左边是假的,检查右边没有意义,答案必须是假的。 因此,这将不会被检查。
boolean a = (x < z) && (x == x);
这种types将会短路,意味着如果(x < z)
评估为false,那么后者不被评估, a
将是假的,否则&&
也将评估(x == x)
。
&
是一个按位运算符,也是一个不会短路的布尔AND运算符。
你可以用下面的方法来testing它们(查看每种情况下调用方法的次数):
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()) { } }
Java提供了大多数其他计算机语言中没有的两个有趣的布尔运算符 AND和OR的二次版本被称为短路逻辑运算符 。 正如你从前面的表格中看到的那样,当A为真时,无论B是什么,OR运算符都是正确的。
类似地,当A为假时,无论B是什么,AND运算符都会导致错误。 如果你使用||
和&&
forms,而不是|
和这些运算符的forms,Java不会单独评估右手操作数。 当右边的操作数依赖于左边的操作数是正确还是错误以便正常工作时,这是非常有用的。
例如,下面的代码片段显示了如何利用短路逻辑评估来确保除法操作在评估之前是有效的:
if ( denom != 0 && num / denom >10)
由于使用了AND( &&
)的短路forms,所以不存在由零除运行exception的风险。 如果这行代码是使用AND的单一版本编写的,则双方都必须进行评估,导致denom
为零时的运行时exception。
在涉及布尔逻辑的情况下,使用AND和OR的短路forms是标准做法,只保留单字符版本用于按位操作。 但是,这个规则也有例外。 例如,请考虑以下声明:
if ( c==1 & e++ < 100 ) d = 100;
在这里,使用单个&
确保将增量操作应用于e
是否等于1。
简而言之,短路意味着停止评估,一旦你知道答案不能再改变。 例如,如果您正在评估一个逻辑AND
的链,并且在该链的中间发现一个FALSE
,那么无论链中其余expression式的值是多less,您都知道结果是错误的。 一个OR
多个连锁也是一样的:一旦你发现一个TRUE
,你马上就知道答案,所以你可以跳过评估其余的expression式。
您向Java表示要通过使用&&
而不是&
和||
来短路 而不是|
。 您的post中的第一组是短路。
请注意,这不仅仅是为了节省几个CPU周期:在像这样的expression式中
if (mystring != null && mystring.indexOf('+') > 0) { ... }
短路意味着正确操作和崩溃之间的差异(在mystring为空的情况下)。
逻辑或: – 如果至less有一个操作数的值为真,则返回true。 这两个操作数在应用OR运算符之前进行评估。
短路OR: – 如果左侧操作数返回true,则返回true,不计算右侧操作数。
if(demon!=0&& num/demon>10)
由于使用了AND(&&)的短路forms,所以当恶魔为零时,没有造成运行时exception的风险。
参考。 由Herbert Schildt编写的Java 2第五版