在java面试题中经常会遇到一些关于finally的问题,我通过class文件研究了一下java编译器对finally的处理。
首先大家需要明白两点:1.如果存在一个finally语句块,必定存在对应的一个try语句块。2.如果程序进入了对应的try语句块执行,不论此try语句块和此try块对应的catch块(如果存在的话)执行了什么样的代码,那么此finally语句块必然要执行。
1.当try块catch块内均不包含return;break;continue;语句时
1.1 如果try块没有抛出异常,那么try语句块执行完毕后,finally块中的语句执行。
1.2 try块抛出异常
1.2.1存在捕捉此异常的catch块,那么catch语句块执行完毕后,执行finally块。
1.2.1不存在捕捉此异常的catch块,执行finally块,抛出异常。
2.try块,catch块含有return;break;continue;时
java编译器会将finally块编译后的字节码放在try和catch块中的这些语句(return;break;continue;)之前。这样便保证了finally语句块肯定会执行。(我使用的编译器是这样做的。较早版本的编译器使用了jsr 指令。)
需要注意的一点是,当方法返回值不为空时,即 return 表达式;那么编译后的语句顺序为
表达式;
finally语句块
返回值入栈;
某个return指令。