先来看一个小程序:
public class JavaException { public static void main(String[] args) { System.out.println(test()); } public static int test() { int i=0; try { i = 1/0;//抛出非受检异常 i=100; System.out.println("in try 抛出异常后不会执行到这里!"); } catch(Exception e) { i=1; System.out.println("in catch i="+i); return i; //注释1 } finally { i=2; System.out.println("in finally i="+i); } i=3; return i; } }
首先来思考一个问题,当我们把注释1那一行也就是catch中的return 语句注释掉和不注释掉程序的输出最后的返回结果分别是什么?
如果不把catch中的return注释掉,返回结果是1,而注释掉catch中的return语句返回结果是3。
为什么呢?我们来调试一下程序,在抛出异常的地方也就是1/0那一行打上断点,然后debug。
我用的是eclipse,所以直接快捷键F6(跳过函数,把函数当做一个整体执行,不进入函数),直接跳到了catch,所以的确是1/0这里出了问题。
继续F6,直到catch中的return语句。
继续单步执行,发现直接跳过了return语句,继续执行finally语句块,继续F6单步执行,发现执行完finally块就直接执行catch块中的return了。
现在我们把catch块中的return语句注释掉来重新调试看一看程序是怎样执行的。
程序还是在1/0的地方抛出异常,然后执行catch块中的语句,再执行finally块中的语句。不过当catch块中没有return语句是,就会执行finally块后面的语句直到遇到return语句。
所以当catch中有return时,test()返回值是1,在catch块中没有return语句时,test()的返回值是3。
那么问题来了,为什么当catch中有return时test()的返回值是1,而不是2,finally中明明已经给i赋值为2了,为什么没有返回2。
在回答这个问题之前,我们先来了解一下java中两种退出方法的方式,
1. 遇到一个返回的指令(return语句)
2. 遇到一个异常,并且没有搜索到异常处理器,不会给调用返回任何值。
所以当catch中有return时,程序遇到return时就被标记了,finally块中只是执行最后的清理工作,如数据库连接的释放等。但是并不会修改return这个语句。
注意:不要在finally块中加入return语句,如果你在finally加入return就会改变你的return语句。如果你使用eclipse这样的IDE,当在finally中有return就会提醒你的代码不正常。
ps:eclipse中常用的调试快捷键的作用
F5(Step Into):就是单步进入,进入是指当代码遇到一个调用方法时进入调用方法的方法体中
F6(Step Over):单步跳过,就是当这一步是一个方法时就把它当做一个整体执行,不进入方法中
F7(Step Return):跳出,就是直接跳出当前正在执行的方法体,返回到调用
F8(Resume):重新开始,当执行到断点的时候,程序被挂起,F8的作用就是让程序继续执行,直到下一个断点重新被挂起