return语句在try-catch-finally中的执行顺序
一般情况下:
public class TryCatchReturn { public static void main(String[] args) { TryCatchReturn tcr = new TryCatchReturn(); System.out.println("tcr.test(): "+tcr.test()); } public int test(){ int a = 0; try{ System.out.println("a: "+a); a = 110; }catch(Exception e){ a = a+3; }finally{ a ++; System.out.println("finally a: "+a);
} return a; } }
执行结果:
a: 0
finally a: 111
tcr.test(): 111
1.首先测试3个块的return的优先级
public class TryCatchReturn { public static void main(String[] args) { TryCatchReturn tcr = new TryCatchReturn(); System.out.println("tcr.test(): "+tcr.test()); } public int test(){ int a = 0; try{ System.out.println("a: "+a); a = 110; return a; }catch(Exception e){ a = a+3; return a; }finally{ //警告: finally block does not complete normally a ++; System.out.println("finally a: "+a); return a; } //return a; //编译报错,不被执行! } }
执行结果:
a: 0
finally a: 111
tcr.test(): 111
可知test()方法最后是从finally模块的return语句返回的;
结论:
1.finally 模块总是会得到执行,且finally模块的return 也总会被执行,而此时try模块的return可以被认为是没有被执行;
2.不推荐在finally模块内return;
2.测试finally块无return时的返回顺序;
public class TryCatchReturn { public static void main(String[] args) { TryCatchReturn tcr = new TryCatchReturn(); System.out.println("tcr.test(): "+tcr.test()); } public int test(){ int a = 0; try{ System.out.println("a: "+a); a = 110; return a; }catch(Exception e){ a = a+3; return a; }finally{ a ++; System.out.println("finally a: "+a); } } }
执行结果:
a: 0
finally a: 111
tcr.test(): 110
test()方法中,try模块的return语句先于finally模块执行,但return并不立即返回,而是执行后,将把返回结果放置进函数栈中,待finally模块执行完后,又返回至try模块的return语句,退出方法,完成执行。因此,对于此种情况,可以认为try模块的return语句先于finally模块执行,但是方法最终还是从return语句返回退出的。
结论:
1. 当try或catch块中有return语句时,finally模块中的语句仍会执行;
2. 当try或catch模块有return语句,若finally模块中无return时,try或catch模块的return返回值在finally模执行前确定的,且return语句先于finally模块执行;
3.当return在try-catch-finally语句之后时,finally模块是在return前执行的;(如首例子所示)
3.测试catch模块介入时return的返回顺序(finally无return);
public class TryCatchReturn { public static void main(String[] args) { TryCatchReturn tcr = new TryCatchReturn(); System.out.println("tcr.test(): "+tcr.test()); } public int test(){ int a = 0; try{ System.out.println("a: "+a); a = 110; throw new Exception(); //try不能return,unreachable }catch(Exception e){ a = a+3; return a; }finally{ a ++; System.out.println("finally a: "+a); } } }
执行结果:
a: 0
finally a: 114
tcr.test(): 113
test()是从catch模块的return语句返回,执行过程类似测试2, finally模块是在catch模块的return执行之前才执行的,且catch模块的return返回值在finally模执行前确定的;
4.测试catch模块介入时return的返回顺序(finally有return);;
public class TryCatchReturn { public static void main(String[] args) { TryCatchReturn tcr = new TryCatchReturn(); System.out.println("tcr.test(): "+tcr.test()); } public int test(){ int a = 0; try{ System.out.println("a: "+a); a = 110; throw new Exception(); //try不能return,unreachable }catch(Exception e){ a = a+3; return a; }finally{ a ++; System.out.println("finally a: "+a); return a;
} } }
执行结果:
a: 0
finally a: 114
tcr.test(): 114
test()是从finally模块的return语句返回的,catch模块的return可被认为是没有执行,且最终返回的是finally模块a的值;
4.总结
1.无论是否有异常,finally块中的语句都会执行,无论try或catch模块是否有return;
2.若finally模块有return,无论try或catch模块中是否有return,程序段最终从finally的return返回;
但一般不推荐在finally语句中return;
3. 若finally模块无return, return语句先于finally模块执行,try或catch模块的return返回值(若有的return的话)在finally模执行前就已经确定,且但方法最终是从return语句返回。
4.对于try-catch-finally语句之后的return语句,finally模块是在return前执行的,且return返回值在finally模执行后确定的;