什么是短路以及如何在Java编程时使用?

可能重复:
在布尔结果已知之后,java是否评估剩余条件?
为什么我们通常使用|| 不是| , 有什么不同?

我有一天错过了我的课堂讲座,我想知道是否有人可以解释什么是短路,也可能是一个简单的Java程序中使用的例子。 谢谢你的帮助!

短路是一旦确定了结果就停止评估expression的地方。 举个例子:

 if (a == b || c == d || e == f) { // Do something } 

如果a == b为真,那么c == de == f 永远不会被评估 ,因为expression式的结果已经被确定了。 如果a == b为假,则c == d被评估; 如果这是真的,那么e == f永远不会被评估。 这似乎没有什么区别,但要考虑到:

 if (foo() || bar() || baz()) { // Do something } 

如果foo()返回true,那么barbaz 永远不会被调用 ,因为expression式的结果已经被确定了。 所以如果barbaz有其他的作用而不仅仅是返回一些东西( 副作用 ),那么这些效果就不会发生。

短路的一个很好的例子涉及客体参考:

 if (a != null && a.getFoo() != 42) { // Do something } 

a.getFoo()通常会抛出NullPointerException如果anull ,但由于expression式短路,如果a != nullfalsea.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 

如果anull ,则不会评估a.size() == 0子expression式,因为布尔运算符|| 如果它的一个操作数是true则计算结果为true

同样,对于这个expression式:

 a != null && a.size() > 0 

如果anull ,则不会评估a.size() > 0 ,因为如果其操作数之一为false则布尔运算符&&计算结果为false

在上面的例子中,布尔运算符&&|| 被认为是短路的,因为如果第一操作数的值足以确定整个expression式的值,则第二操作数可能不被评估。 为了比较, &| 操作数是等效的非短路布尔运算符。

短路是使用逻辑AND或OR运算符的另一种方法(&或|)

例如非短路OR

 if(false | true) { } 

第一个条件和第二个条件都被评估,即使假是不正确的(总是这样)。

然而它被写成短路或者:

 if(false || true) { } 

第一个条件是只评估,因为它是假的,真正的不被评估,因为它不是必需的。

Interesting Posts