复习一下finally块里有return和try抛异常的程序执行顺序问题.
首先看一个测试例子:
public class FinallyTryTest {
public static void main(String[] args) {
int a=testFinally();
System.out.println(a);
}
public static int testFinally(){
int count=10;
try{
throw new RuntimeException("测试异常");
}catch(Exception e){
System.out.println(e.getMessage());
}
finally {
System.out.println("finally块被执行");
return count;
}
}
}
在运行之前先简单分析一下,可能会说这么简单,不是一眼就看出来了吗?结果如下:
测试异常
finally块被执行
10
可能会说,比较容易,执行顺序不就是先try->catch->finally->return 结束方法->输出count的值吗?
说明一点:如果finally块里面有return语句会导致方法结束的,不会再次跳回try块,catch块里面执行任何代码了的.
下面的例子先看一下:
public class FinallyTryTest {
public static void main(String[] args) {
int a=testFinally();
System.out.println(a);
}
public static int testFinally(){
int count=10;
try{
throw new RuntimeException("测试异常");
}
finally {
System.out.println("finally块被执行");
return count;
}
}
}
就是把catch块给去掉了的.猜一下程序的运行结果吧.想一想该程序的执行过程是怎样的?
首先:每个try块至少对应一个catch块或者是一个finally块,不能能是只有唯一的一个try块的.上述程序满足不会报编译错误的.
接下来在分析执行的结果会是什么样的?猜测的依据是什么?该程序的执行过程又是什么?不妨看一下.
1:会报异常没有输出结果.
2:报异常有输出结果.
3:没报异常,程序正常输出.
正确的答案是3号.
有图有真相
如何验证猜想的每一步的执行过程呐?那就Debug吧.下面是分别每一步的Debug的执行过程的截图.红色箭头表示执行到那一行.
至此完成所有程序的执行过程.看到非常直观的结论throw语句完全失去了作用.
实验完成了总结一下吧.
不论try块是正常结束,还是非正常中途退出,finally块其实都会执行的.(这里说明一点try块根本就没有结束它的执行过程,如果要是通过System.exit(0)将停止当前线程和已经死亡的线程,finally块难道能让已经停止的线程继续吗?当然不能能啦.)
执行流程,当程序执行try块,catch块时遇到throw语句的时候,try块就检查该异常处理流程里面是否包含finally块,如果没有,那就是相应的catch块那就捕获这个异常.如果有finally块,并且有catch块捕获就会先捕获这个异常,再开始执行finally块.如果只有finally块(没有相应的catch块捕获该异常)只有当finally块执行完成后,系统才会再次跳回来抛出异常的.如果finaly块里使用return语句就结束了方法.就不会再次跳回try块里面的.
catch块里面含有return语句,不会立即结束当前的方法的,会先检查是否有finally块的.如果有就会执行的.如果finally块里面有return语句就会结束方法的.这个时候就真的结束了,不会在执行其他的块里面的代码的.
通过Debug可以清楚的看到执行的过程.胜于理论概念(万一理论分析出现偏差).