Java逻辑运算符短路
哪一组短路了,复杂条件表达式短路到底意味着什么?
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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
&&
和||
运算符“短路”,这意味着如果不需要,它们不会计算右侧。&
和|
运算符用作逻辑运算符时,始终对两边求值。每个运算符只有一种短路情况,它们是:
false && ...
- 不必知道右侧是什么,因为无论其值如何false
... - 没有必要知道右侧是什么,因为无论那里的值如何,结果都只能是true
来比较行为:
让我们通过一个简单的示例 第二个版本使用非短路运算符
&
,如果input
为null
,则会抛出NullPointerException
,但第一个版本将返回false
无一例外。The
&&
and||
operators "short-circuit", meaning they don't evaluate the right-hand side if it isn't necessary.The
&
and|
operators, when used as logical operators, always evaluate both sides.There is only one case of short-circuiting for each operator, and they are:
false && ...
- it is not necessary to know what the right-hand side is because the result can only befalse
regardless of the value theretrue || ...
- it is not necessary to know what the right-hand side is because the result can only betrue
regardless of the value thereLet's compare the behaviour in a simple example:
The 2nd version uses the non-short-circuiting operator
&
and will throw aNullPointerException
ifinput
isnull
, but the 1st version will returnfalse
without an exception.SET A 使用短路布尔运算符。
在布尔运算符的上下文中,“短路”的含义是,对于一组布尔值 b1、b2、...、bn,一旦这些布尔值中的第一个为真,短路版本就会停止计算 (|| ) 或假 (&&)。
例如:
SET A uses short-circuiting boolean operators.
What 'short-circuiting' means in the context of boolean operators is that for a set of booleans b1, b2, ..., bn, the short circuit versions will cease evaluation as soon as the first of these booleans is true (||) or false (&&).
For example:
短路意味着如果第一个操作员决定了最终结果,则不会检查第二个操作员。
例如表达式为: True || False
对于 ||,我们只需要其中一侧为 True。因此,如果左侧为真,则检查右侧没有意义,因此根本不会检查右侧。
同样,False && True
对于 &&,我们需要两边都为 True。因此,如果左侧为 False,则检查右侧就没有意义,答案必须为 False。因此根本不会被检查。
Short circuiting means the second operator will not be checked if the first operator decides the final outcome.
E.g. Expression is: True || False
In case of ||, all we need is one of the side to be True. So if the left hand side is true, there is no point in checking the right hand side, and hence that will not be checked at all.
Similarly, False && True
In case of &&, we need both sides to be True. So if the left hand side is False, there is no point in checking the right hand side, the answer has to be False. And hence that will not be checked at all.
这种类型会短路,这意味着如果
(x < z)
计算结果为 false,则不会计算后者,a
将为 false,否则& &
还将评估(x == x)
。&
是一个按位运算符,也是一个不短路的布尔 AND 运算符。您可以通过以下方式测试它们(查看每种情况下调用该方法的次数):
This kind will short-circuit, meaning if
(x < z)
evaluates to false then the latter is not evaluated,a
will be false, otherwise&&
will also evaluate(x == x)
.&
is a bitwise operator, but also a boolean AND operator which does not short-circuit.You can test them by something as follows (see how many times the method is called in each case):
简单来说,短路意味着一旦你知道答案不能再改变就停止评估。例如,如果您正在评估逻辑
AND
链,并且发现该链中间有一个FALSE
,您就知道结果将是 false,不不管链中其余表达式的值是多少。对于OR
链也是如此:一旦发现TRUE
,您就会立即知道答案,因此您可以跳过计算其余表达式。您可以通过使用
&&
而不是&
和||
而不是| 向 Java 表明您想要短路。
。您帖子中的第一组是短路。请注意,这不仅仅是节省一些 CPU 周期的尝试:在像这样的表达式中,
短路意味着正确操作和崩溃之间的区别(在 mystring 为 null 的情况下)。
In plain terms, short-circuiting means stopping evaluation once you know that the answer can no longer change. For example, if you are evaluating a chain of logical
AND
s and you discover aFALSE
in the middle of that chain, you know the result is going to be false, no matter what are the values of the rest of the expressions in the chain. Same goes for a chain ofOR
s: once you discover aTRUE
, you know the answer right away, and so you can skip evaluating the rest of the expressions.You indicate to Java that you want short-circuiting by using
&&
instead of&
and||
instead of|
. The first set in your post is short-circuiting.Note that this is more than an attempt at saving a few CPU cycles: in expressions like this
short-circuiting means a difference between correct operation and a crash (in the case where mystring is null).
&
和&&
运算符之间存在一些差异。同样的差异也适用于|
和||
。最重要的是要记住,&&
是一个逻辑运算符,仅适用于布尔操作数,而&
是适用于整数类型和布尔值的按位运算符。通过逻辑运算,您可以进行短路,因为在某些情况下(例如
&&
的第一个操作数为false
,或者| 的第一个操作数) |
为true
),您无需计算表达式的其余部分。这对于执行诸如在访问字段或方法之前检查null
以及在除以它们之前检查潜在的零等操作非常有用。对于复杂表达式,表达式的每个部分都以相同的方式递归计算。例如,在以下情况下:仅评估强调的部分。要计算
||
,首先检查7 == 8
是否为true
。如果是这样,右侧将被完全跳过。右侧仅检查1 == 3
是否为false
。既然如此,就不需要检查4 == 4
,并且整个表达式的计算结果为false
。如果左侧为true
,例如7 == 7
而不是7 == 8
,则整个右侧将被跳过,因为无论如何,整个||
表达式将为true
。对于按位运算,您需要计算所有操作数,因为您实际上只是组合位。在 Java 中,布尔值实际上是一位整数(无论内部如何工作),在这种特殊情况下,您可以对按位运算符进行短路,这只是一个巧合。不能短路一般整数
&
或|
操作的原因是,任一操作数中的某些位可能打开,某些位可能关闭。类似于1 & 2
产生零,但是如果不评估两个操作数,您就无法知道这一点。There are a couple of differences between the
&
and&&
operators. The same differences apply to|
and||
. The most important thing to keep in mind is that&&
is a logical operator that only applies to boolean operands, while&
is a bitwise operator that applies to integer types as well as booleans.With a logical operation, you can do short circuiting because in certain cases (like the first operand of
&&
beingfalse
, or the first operand of||
beingtrue
), you do not need to evaluate the rest of the expression. This is very useful for doing things like checking fornull
before accessing a filed or method, and checking for potential zeros before dividing by them. For a complex expression, each part of the expression is evaluated recursively in the same manner. For example, in the following case:Only the emphasized portions will evaluated. To compute the
||
, first check if7 == 8
istrue
. If it were, the right hand side would be skipped entirely. The right hand side only checks if1 == 3
isfalse
. Since it is,4 == 4
does not need to be checked, and the whole expression evaluates tofalse
. If the left hand side weretrue
, e.g.7 == 7
instead of7 == 8
, the entire right hand side would be skipped because the whole||
expression would betrue
regardless.With a bitwise operation, you need to evaluate all the operands because you are really just combining the bits. Booleans are effectively a one-bit integer in Java (regardless of how the internals work out), and it is just a coincidence that you can do short circuiting for bitwise operators in that one special case. The reason that you can not short-circuit a general integer
&
or|
operation is that some bits may be on and some may be off in either operand. Something like1 & 2
yields zero, but you have no way of knowing that without evaluating both operands.Java 提供了大多数其他计算机语言中没有的两个有趣的布尔运算符。 AND 和 OR 的这些辅助版本称为短路逻辑运算符。从上表中可以看出,无论 B 是什么,当 A 为 true 时,OR 运算符的结果都是 true。
类似地,当 A 为假时,无论 B 是什么,AND 运算符都会得出假。如果您使用
||
和&&
形式,而不是|
和&
形式对于这些运算符,Java 不会费心单独计算右侧操作数。当右侧操作数取决于左侧操作数的真或假才能正常运行时,这非常有用。例如,以下代码片段显示了如何利用短路逻辑求值来确保除法运算在求值之前有效:
由于 AND (
&&<使用 /code>) 时,不存在因除零而导致运行时异常的风险。如果这行代码是使用单个
&
版本的 AND 编写的,则必须对两边进行求值,从而在denom
为零时导致运行时异常。在涉及布尔逻辑的情况下,标准做法是使用 AND 和 OR 的短路形式,而将单字符版本专门用于按位运算。但是,此规则也有例外。例如,考虑以下语句:
这里,使用单个
&
确保无论c
是否相等,递增操作都将应用于e
为 1 或不为 1。Java provides two interesting Boolean operators not found in most other computer languages. These secondary versions of AND and OR are known as short-circuit logical operators. As you can see from the preceding table, the OR operator results in true when A is true, no matter what B is.
Similarly, the AND operator results in false when A is false, no matter what B is. If you use the
||
and&&
forms, rather than the|
and&
forms of these operators, Java will not bother to evaluate the right-hand operand alone. This is very useful when the right-hand operand depends on the left one being true or false in order to function properly.For example, the following code fragment shows how you can take advantage of short-circuit logical evaluation to be sure that a division operation will be valid before evaluating it:
Since the short-circuit form of AND (
&&
) is used, there is no risk of causing a run-time exception from dividing by zero. If this line of code were written using the single&
version of AND, both sides would have to be evaluated, causing a run-time exception whendenom
is zero.It is standard practice to use the short-circuit forms of AND and OR in cases involving Boolean logic, leaving the single-character versions exclusively for bitwise operations. However, there are exceptions to this rule. For example, consider the following statement:
Here, using a single
&
ensures that the increment operation will be applied toe
whetherc
is equal to 1 or not.逻辑或:- 如果至少一个操作数的计算结果为 true,则返回 true。在应用 OR 运算符之前,将对两个操作数进行评估。
短路或:- 如果左侧操作数返回 true,则返回 true,而不评估右侧操作数。
Logical OR :- returns true if at least one of the operands evaluate to true. Both operands are evaluated before apply the OR operator.
Short Circuit OR :- if left hand side operand returns true, it returns true without evaluating the right hand side operand.
由于使用了 AND(&&) 的短路形式,因此当 demo 为零时,不存在导致运行时异常的风险。
参考号Java 2 第五版 作者:Herbert Schildt
Since the short-circuit form of AND(&&) is used, there is no risk of causing a run-time exception when demon is zero.
Ref. Java 2 Fifth Edition by Herbert Schildt
来自 docs.oracle 的文档
由于逻辑表达式是从左到右计算的,因此使用以下规则对它们进行可能的“短路”计算测试:
逻辑规则保证这些评估总是正确的。请注意,上述表达式的任何部分都不会被求值,因此这样做的任何副作用都不会生效。
https://docs.oracle.com/cd/E57185_01/HIRUG/ch31s05s01。 html
Document from docs.oracle
As logical expressions are evaluated left to right, they are tested for possible “short-circuit” evaluation using these rules:
The rules of logic guarantee that these evaluations are always correct. Note that the anything part of the above expressions is not evaluated, so any side effects of doing so do not take effect.
https://docs.oracle.com/cd/E57185_01/HIRUG/ch31s05s01.html