什么是短路以及如何在Java编程时使用?
可能重复:
在布尔结果已知之后,java是否评估剩余条件?
为什么我们通常使用||
不是|
, 有什么不同?
我有一天错过了我的课堂讲座,我想知道是否有人可以解释什么是短路,也可能是一个简单的Java程序中使用的例子。 谢谢你的帮助!
短路是一旦确定了结果就停止评估expression的地方。 举个例子:
if (a == b || c == d || e == f) { // Do something }
如果a == b
为真,那么c == d
和e == f
永远不会被评估 ,因为expression式的结果已经被确定了。 如果a == b
为假,则c == d
被评估; 如果这是真的,那么e == f
永远不会被评估。 这似乎没有什么区别,但要考虑到:
if (foo() || bar() || baz()) { // Do something }
如果foo()
返回true,那么bar
和baz
永远不会被调用 ,因为expression式的结果已经被确定了。 所以如果bar
或baz
有其他的作用而不仅仅是返回一些东西( 副作用 ),那么这些效果就不会发生。
短路的一个很好的例子涉及客体参考:
if (a != null && a.getFoo() != 42) { // Do something }
a.getFoo()
通常会抛出NullPointerException
如果a
为null
,但由于expression式短路,如果a != null
为false
, a.getFoo()
部分永远不会发生,所以我们不会发生exception。
请注意,并非所有expression式都是短路的。 ||
和&&
操作员短路,但是|
和&
不是,也不是*
或/
实际上大多数运营商都没有。
短路评估意味着当评估布尔expression式(逻辑“ AND
和“ OR
)时,只要find满足或否定expression式的第一个条件就可以停止。
例如,假设你正在用几个子expression式评估一个逻辑OR
,每个子expression式的评估代价都很高:
if (costlyTest1() || costlyTest2() || costlyTest3()) { // ...
JVM可以停止评估“costlyTest”函数,只要它find一个返回true
函数,因为它将满足布尔expression式。 所以如果costlyTest1()
返回true,那么其他testing将被跳过。 同理:
if (costlyTest1() && costlyTest2() && costlyTest3()) { // ...
JVM可以停止评估函数,只要它发现返回false
的函数,因为它也满足expression式; 所以如果costlyTest1()
返回false,那么其他函数将不会被调用。
这些规则与布尔expression式的嵌套级别有关,可以利用这些规则来避免不必要的工作,如上面的例子所示。
Short Circuit
:如果第一部分是true
请不要打扰评估expression式的其余部分。 在&&
也是短路的情况下,同样的逻辑适用于false
expression式评估的短路意味着只有一部分expression式在查找其值之前需要进行评估。 例如:
a == null || a.size() == 0
如果a
为null
,则不会评估a.size() == 0
子expression式,因为布尔运算符||
如果它的一个操作数是true
则计算结果为true
。
同样,对于这个expression式:
a != null && a.size() > 0
如果a
为null
,则不会评估a.size() > 0
,因为如果其操作数之一为false
则布尔运算符&&
计算结果为false
。
在上面的例子中,布尔运算符&&
和||
被认为是短路的,因为如果第一操作数的值足以确定整个expression式的值,则第二操作数可能不被评估。 为了比较, &
和|
操作数是等效的非短路布尔运算符。
短路是使用逻辑AND或OR运算符的另一种方法(&或|)
例如非短路OR
if(false | true) { }
第一个条件和第二个条件都被评估,即使假是不正确的(总是这样)。
然而它被写成短路或者:
if(false || true) { }
第一个条件是只评估,因为它是假的,真正的不被评估,因为它不是必需的。