内容简介:异常是Java核心中非常重要的一个概念,但却很容易被大家忽略,这个系列我们会深入讲一下这个话题。学完这个系列,相信会让你对异常体系以及异常的各种使用场景,了如指掌,成为你职业进阶的必备技能。在之前的但 try-with-resources 语句仅仅适用于自动关闭资源,有些场景下我们需要无论一段代码发生异常与否,都需要执行另外一段代码,这个时候就需要使用 finally 块了。
异常是 Java 核心中非常重要的一个概念,但却很容易被大家忽略,这个系列我们会深入讲一下这个话题。学完这个系列,相信会让你对异常体系以及异常的各种使用场景,了如指掌,成为你职业进阶的必备技能。
| 名称 | 状态 |
|---|---|
| finally 的真正运行时机 | 已完成 |
| try-with-resources 语句 | 已完成 |
| Java 异常体系 | 创作中... |
| catch 中的异常参数 | 创作中... |
| Java 异常链 | 创作中... |
| SpringMVC 中的异常处理 | 创作中... |
| 自定义 SpringMVC 的异常处理链 | 创作中... |
在之前的 Java语法糖 : 使用 try-with-resources 语句安全地释放资源 一文中,我们介绍了如何通过 try-with-resources 语句来代替丑陋的 finally 块。
但 try-with-resources 语句仅仅适用于自动关闭资源,有些场景下我们需要无论一段代码发生异常与否,都需要执行另外一段代码,这个时候就需要使用 finally 块了。
如果有人问你 发生异常以后 finally 块的内容什么时候会执行?你也许会毫不犹豫地回答:当然是执行完 catch 块的内容以后执行了。
但有时候你的回答也许没法这么干脆,比如下面这个例子。
当在 catch 块和 finally 块同时 return 的时候,到底会 return 什么呢?
public static int testFinally1() {
try {
Integer.parseInt("exception here");
} catch (Exception e) {
System.out.println("catch block 1");
return 11;
} finally {
System.out.println("finally block 1");
return 12;
}
}
复制代码
事实上,即使 catch 块有 return 语句, finally 块必然执行的逻辑还是成立的。上面的方法, return 的是 12 。先输出 catch block 1 ,然后输出 finally block 1 ,最后返回 12 。
不知道你发现规律没有,下面再举个例子你就更清晰了。
public static int testFinally3() {
try {
System.out.println("start");
Integer.parseInt("testFinally3");
System.out.println("never run");
} catch (Exception e) {
System.out.println("catch block 3");
return iamReturn();
} finally {
System.out.println("finally block 3");
}
return 31;
}
public static int iamReturn() {
System.out.println("return block");
return 666;
}
复制代码
思考一下执行这个方法会分别输出和返回什么?
先别着急看答案,根据我们之前发现的规律, finally 块必然执行,而 catch 块的非 return 部分需要在 finally 块之前执行。那么最终返回的应该是 666 。
答案确实如此。下面是控制台输出的顺序:
start catch block 3 return block finally block 3 复制代码
由此,我们可以总结 finally 块的真正运行时机了:
- finally 块必然执行,不论发生异常与否,也不论在 finally 之前是否有
return。 - 不管在 try 块中还是在 catch 块中包含 return,finally 块总是在
return之前执行。 - 如果 finally 块中有
return,那么 try 块和 catch 块中的return就没有执行机会了。
如果你真的理解了finally 块的真正运行时机,那么请思考一下,下面程序的返回值是 21 还是 22 ,欢迎留言讨论。
public static int testFinally2() {
try {
System.out.println("start");
return 21;
} catch (Exception e) {
System.out.println("catch block 2");
} finally {
System.out.println("finally block 2");
}
return 22;
}
复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 封装中修改旧代码的时机
- 监听reloadData刷新列表完毕的时机
- 国内存储芯片迎来最好的发展时机
- 虚拟机类加载机制:类加载时机
- 什么时候才是代码重构的最佳时机?
- JVM类生命周期概述:加载时机与加载过程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机网络(第4版)
[美] James F. Kurose、[美] Keith W. Ross / 陈鸣 / 机械工业出版社 / 2009-11 / 66.00元
本书采用了独创的自顶向下方法,即从应用层开始沿协议栈向下讲解计算机网络的基本原理,强调应用层范例和应用编程接口,内容深入浅出,注重教学方法,理论与实践相结合。第3版的内容相应更新并反映了网络领域的最新进展,如增加了无线和移动网络一章,扩充了对等网络、BGP、MPLS、网络安全、广播选路和因特网编址及转发方面的材料;还增加了一套实用的实验,并修订了习题。本书适合作为计算机、电子、通信工程相关专业的本......一起来看看 《计算机网络(第4版)》 这本书的介绍吧!