Java中逻辑表达式的短路(先理解运算符的优先级)

时间:2021-08-22 18:58:56

在学习Java中逻辑表达式中的短路机制之前, 我们必须明确一点:

就是运算符优先级与执行顺序的问题,  运算符优先级高的表达式在执行时会被视为一个整体,  但是对于除赋值符外的所有二元运算符来说,  执行的顺序始终是从左到右执行的.

比如 1 + 2 + (3 + 4) 这个式子, 括号的优先级最高, 所以括号内的表达式被视为一个整体, 执行顺序是 1+2+(整体), 先执行了1 + 2再遇到括号内的整体, 再执行整体内的表达式.

再不会混淆的前提下理解短路机制, 我们就必须先知道优先级与执行顺序没有必然联系.


实例:

/** 
* 测试运算符的优先级是否与执行顺序有关
* @author libertine1993
*/
public class TestOrder{
public static int test(int para){
System.out.println("called with para = " + para);
return para;
}

public static void main(String[] args){
int i = test(0) + test(1) - test(2) * test(3);
System.out.println("-------------------------");

i =test(0) + test(1) + test(2) + ( test(3) - test(4) );
System.out.println("-------------------------");

i = ( test(0) - test(1) ) + test(2) + test(3) * test(4);
}

}

输出结果:

Java中逻辑表达式的短路(先理解运算符的优先级)

第一个表达式 " test(2) * test(3)" 拥有较高的优先级, 所以会被视为一个整体, 但是程序的执行顺序还是从左到右, 因此调用的顺序是 test(0), test(1), test(2), test(3) 

第二个表达式理同第一个.

第三个表达式执行顺序是 (整体) , test(2), test(3), test(4)

对于++, --,这种运算符的解释, 也一样 a + ++b 的执行顺序是从左往右, a + (整体), 整体是++b


在明确了Java运算符优先级高的表达式会被视为整体, 但是执行顺序还是从左到右之后我们再来看Java的逻辑表达式的短路机制.

逻辑表达式的短路机制:

在Java中, 在已经能够确定整个逻辑表达式的值的情况下, 就会对整个逻辑表达式进行求值, 也就是说会有部分的条件不会被判断到, 因为我们已经能够确定整个逻辑表达式的值了(当然这种机制仍然要遵循表达式执行的顺序).


举个简单的例子:

import java.util.*;

public class ShortCircuit{
public static boolean test(int para){
System.out.println("test is called with para = " + para);
return para > 5;
}

public static void main(String[] args){
System.out.println("----------------------------------------");
//与运算的短路条件: 同一级别的逻辑表达式, 前面的条件为false, 该级别的表达式就确定为假, 后面的表达式无需运算
if(test(0) && test(6) && test(1) && test(2) && test(3)){}

System.out.println("----------------------------------------");
//或运算的短路条件: 同一级别的逻辑表达式, 前面的条件为true, 该级别的表达式就确定为真, 后面的表达式无需运算
if(test(6) || test(0) || test(1) || test(2) || test(3)){}
}
}
输出:

Java中逻辑表达式的短路(先理解运算符的优先级)


第一个表达式, 因为test(0) 为false, 故整个表达式的值已经确定为false, 发生了短路, 后面的条件均没有判断.

第二个表达式,  因为test(6)为true, 此时整个表达式的值已经确定为true, 同样发生短路.


接下来的例子就是我们在介绍短路机制之前, 特地要说明运算符优先级与执行顺序的原因

import java.util.*;

public class ShortCircuit{
public static boolean test(int para){
System.out.println("test is called with para = " + para);
return para > 5;
}

public static void main(String[] args){
System.out.println("----------------------------------------");
if(test(8) || test(1) && test(4)){}

System.out.println("----------------------------------------");
//嵌套的逻辑表达式, 短路的判断会逐级别判断
if( (test(9) || test(6) || test(7)) || test(8) && test(1)){}
/*内层逻辑表达式 test(0) && test(6) && test(7) */
}
}

输出:

Java中逻辑表达式的短路(先理解运算符的优先级)


第一个表达式中, &&的优先级高 (关于&&的优先级高于||, 有疑惑的请拉至最下方, 参考来自Sun的官方文档给出的优先级表格),  所以test(1) && test(4) 会被当成整体, 外层的逻辑表达式是 test(8) || (整体), 故因为test(8) 为真, 整个逻辑表达式的值已确定为真, 故发生短路, 只判断了test(8)的条件.


第二个表达式说明, 短路机制的判断会发生在每一层的逻辑表达式当中(当然仍然得遵循执行顺序).内层表达式 test(9) || test(6) || test(7) 只判断了test(9) 就短路, 然后进入(整体) ||  test(8) && test(1) 这一层, 整体为真, 又短路.




Java官方文档运算符优先级:

Java中逻辑表达式的短路(先理解运算符的优先级)