异常处理执行顺序
1.情景
昨天老大考我一个基础知识,当时没遇到过这种情况不能确定下来答案。话不多说,上代码。
是两个很基本的方法:
/**
* 测试基本数据类型在try-catch-finally里遇到异常的返回情况
* @return
*/
public static int test1(){
int a = 1 ;
ArrayList<Object> list = new ArrayList<>();
try {
a = 2;
int b = a/0;
System.out.println("a1 ="+ a);
//写一个会异常的情况
return a;
} catch (Exception e) {
a = 3;
System.out.println("a2 ="+a);
return a;
} finally {
a = 4;
System.out.println("a3 ="+a);
return a;
}
}
/**
* 测试集合在try-catch-finally里遇到异常的返回情况
* @return
*/
public static List test2(){
int a = 1 ;
ArrayList<Object> list = new ArrayList<>();
try {
list.add(2);
int c = a/0;
System.out.println("list ="+ list);
//写一个会异常的情况
return list;
} catch (Exception e) {
list.add(3);
System.out.println("list ="+ list);
return list;
} finally {
list.add(4);
System.out.println("list ="+ list);
return list ;
}
}
然后调用,开启测试。
public class demo1 {
public static void main(String[] args) {
Test test = new Test();
int a = Test.test1();
//List list = Test.test2();
System.out.println("最后的a:"+ a);
//System.out.println("最后的list"+list);
}
}
2. 结果
test1的结果:
test2的结果:
3. 分析
首先我们先不看最后的返回值,先看a1、a2、a3的执行顺序
a1没有打印出来因为下方的异常,然后就直接跳到catch里面了,然后就将a2打印出来,最后进入到 finally 里面 ,然后打印a3。
这个也就是try catch finally 遇到异常的执行顺序了。
然后我们再来分析最后返回的值,对于test1的最终返回值a 是4 ,也就是最终返回值是finally的返回值;而对于test2的最终返回值,就是list 则会是 2、3、4都会有。
4.结论
return返回值的机制就是将返回值存入eax寄存器中,然后系统再将eax中的值赋给变量(i)。
可以理解为这个return是像是靠栈来实现的,根据栈先进后出的特点,所以会去拿最后的值,也就是最后的返回值。
所以按照前面方法的情景下就是只会返回到finally的值,所以当为基本数据类型时会返回3,为集合时会返回2、3、4,因为集合也可以自己存的嘛。
所以实际开发中,尽量不要在finally里去返回值,不然很可能会覆盖之前的值。
Return详细原理和分析可以看看这两篇加强一波:
C/C++ return 如何实现的?return 的内部机制
return机制
深刻的感受到了自己太菜了,需要学的还有很多了,加强加强!