已知:try/catch-finally 最后函数节数肯定会执行finally内容。如果try中没有异常,不会执行catch,如果有异常,先执行catch.
代码1
public class try_catch_finally {
static int res = 0;
public static void main(String[] args) {
System.out.println(add()); // 步骤5
}
public static int add() {
try {
res++; // 步骤1
return res/0; // 步骤2
}catch (Exception e) {
System.out.println(e.getMessage()); // 步骤3
}finally {
System.out.println("finally"); // 步骤4
}
return res;
}
}
输出
/ by zero // 执行步骤3输出
finally // 执行步骤4输出
1 // 执行步骤5输出
代码2
public class try_catch_finally {
static int res = 0;
public static void main(String[] args) {
System.out.println(add());
}
public static int add() {
try {
res++;
return res; // 步骤 a
}catch (Exception e) {
System.out.println(e.getMessage());
}finally {
res++; // 步骤 b
System.out.println("finally");
}
return res;
}
}
输出
finally
1
疑问:既然finally中的代码是必须执行的,函数在最后才会返回,那么最后执行步骤a的时候,res应该已经执行了步骤b了呀。
单步调试,步骤a - > 步骤b - > 步骤 a
猜测,第一次执行到步骤a的时候,把res的值保存了,用于最后返回,后面finally修改res的时候就不影响最后的返回结果。
查阅资料得到答案:
try{
return expression;
}catch(){
xxx
}finally() {
xxx
}
执行顺序:
- 执行:expression,计算该表达式,结果保存在操作数栈顶;
- 执行:操作数栈顶值(expression的结果)复制到局部变量区作为返回值;
- 执行:finally语句块中的代码;
- 执行:将第2步复制到局部变量区的返回值又复制回操作数栈顶;
- 执行:return指令,返回操作数栈顶的值;
在第一步就已经确定了返回值,被临时保存到局部变量区了,最后用于返回。finally操作的代码无法影响返回值,除非,finally返回 return;
答案部分的逻辑参考 JAVA中return与finally的先后关系
参考博客:https://blog.csdn.net/sinat_22594643/article/details/80509266?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-4.control&dist_request_id=1328740.12942.16168347167333631&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-4.control