Java语言中try-catch-finally的执行顺序
来源:互联网 发布:考研网课哪家好 知乎 编辑:程序博客网 时间:2024/05/11 15:35
最近遇到一道Java编程题目,让根据以下程序写输出:
public static int func (){ try{ return 1; }catch (Exception e){ return 2; }finally{ return 3; }}按着之前的想法,finally肯定会执行,但return这么多,猜想是编译错误,正确答案是3。遂在查找各种资料,找到了几处权威的,整理如下。
-------------------分割线----------------
finally的作用
对于一些代码,无论try块中的异常是否会抛出,它们都得执行。这通常适用于内存回收之外的资源清理工作(内存回收由后台GC线程自动完成),如已经打开的文件或网络连接,屏幕上画的图形,数据库连接等等。那么这些代码就可以放到finally子句内。
finally的使用
finally正常的使用大家都比较常见,但在再次抛出异常、与return结合等情况下,容易产生迷惑,所以整理为下面几节。
异常再次抛出时
finally语句总会执行,甚至在异常没有被当前异常处理程序捕获,而重新抛出给更高一层前,finally会执行,例子是《Java编程思想》里的,如图:
在return中使用finally
由于finally总会执行,所以如果在return中使用finally,就可从多个点返回,同时保证重要的、必须的工作仍旧执行,即在含有finally的函数中,从何处返回无关紧要,示例如下:
public class TryCatchFinally{public static int func(int i){System.out.println("func");try{System.out.println("try block");if(i == 1) return 1;if(i == 2) return 2;if(i == 3) return 3;return -1;}catch (Exception e){System.out.println("catch block");return -2;}finally{System.out.println("finally block");}}public static void main(String[] args){for(int i=1; i <= 4; i++){System.out.println(func(i));System.out.println("-----------");}}}运行后输出内容为:
functry blockfinally block1-----------functry blockfinally block2-----------functry blockfinally block3-----------functry blockfinally block-1-----------注意:这里catch必须有返回值,否则报错。究其原因,是因为函数必须有返回值,如果try里面出错,try里的return就无效了,而finally、catch里都没有return,所以这两个字句必须至少有一个包含有返回值。
finally的优先覆盖
这里还需要指出,finally子句有最高的控制流返回权,其可以覆盖try、catch块内的任意Exception值、return值。如下的函数,将会返回12,而不是10。
public static int getMonthsInYear(){ try{ return 10; } finally { return 12; }}同样地,如下函数,最后并不会抛出异常,而是返回值。
public static int getMonthsInYear(){ try{ throw new RuntimeException(); } finally { return 12; }}再对比这个函数,却抛出异常,并不返回值。
public static int getMonthsInYear(){ try{ return 12; } finally { throw new RuntimeException(); }}
finally不执行的特殊情况
finally子句一定会执行,除了极少的极端情况:
- 调用了
System.exit()
- Java虚拟机崩了
总结
finally子句一定会执行,如果其含有程序控制流返回的语句,如return、throw e等,那么try、catch子句的相应控制流语句会失效;反之,当finally里没有控制流返回语句时,就会返回try或catch的控制流返回处,进行正常控制流交还操作。当然,这种编程方式是极不友好的,大概也只有在面试的时候能遇到吧。
另外,参考里给的stachoverflow的链接里,有几个回答很好,比如有个牛人直接贴出了Java语言规范(JLS),有的一句话就点清,上面最后的三段代码就是参考的某个高票回答,想深入了解的请继续阅读探索。
参考:
1. 《Java编程思想》 P264
2. http://stackoverflow.com/questions/65035/does-finally-always-execute-in-java
3.https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17
4.https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.1
- Java语言中try-catch-finally的执行顺序
- Java语言中try-catch-finally的执行顺序
- java 中try catch finally执行顺序
- Java try catch finally的执行顺序
- Java try catch finally的执行顺序
- Java try catch finally的执行顺序
- Java try catch finally的执行顺序
- Java try catch finally的执行顺序
- java try-catch-finally的执行顺序
- java中try catch finally与return的执行顺序
- java 中try catch finally 语句的执行顺序
- java 中try catch finally 语句的执行顺序
- 关于java中try catch finally的执行顺序
- java 中 try catch finally 语句的执行顺序
- Java中try-catch-finally-return的执行顺序
- java中try{}catch{}和finally{}的执行顺序问题
- 关于Java中try-catch-finally-return的执行顺序
- 关于Java中try-catch-finally-return的执行顺序
- codeforces-148C-Terse princess【构造】
- binary-tree-postorder-traversal
- jQuery中的Ajax
- Java中的Xml文件解析(DOM)
- android 学习心得
- Java语言中try-catch-finally的执行顺序
- CVTE android实习生一面经验 ----回忆版本
- Java 多线程(七)——线程组与线程池
- shell中调用sqlplus
- Activty 双击返回键退出应用
- 程序员之路的感悟(一)
- jQuery常用相关插件
- 二叉搜索树的一种构造方法
- Linux安装JDK