Java Magic. Part 3: Finally
Java Magic. Part 3: Finally
@(Base)[JDK, magic, 黑魔法]
转载请写明:原文地址
英文原文
系列文章:
-Java Magic. Part 1: java.net.URL
-Java Magic. Part 2: 0xCAFEBABE
-Java Magic. Part 3: Finally
-Java Magic. Part 4: sun.misc.Unsafe
所有JAVA程序员都应该知道一个基本概念-finally一定会被执行,但是真的是这样么?
这取决于“执行”是什么意思。但总的来说答案都是,YES。
Normal program execution
有人可能拿如下的例子来反驳:
try {
System.exit(1);
} finally {
System.out.println("I'm here, man");
}
刚才是不是你说的finlly块一定会被执行。
显然在上面这个例子中,Sout语句不会被执行。我们刚才也说了,是正常的程序六层中答案是肯定的。
下面这句话来自官方文档
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
我们再看下面这段代码,第二行是不是一定会执行呢?
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
答案仍然是肯定的。除非...BANG...断电了,程序终止。
这是神马意思呢?意思就是程序非正常的运行。我们没办法保证所有事情。显然,这和System.exit(1)是一个意思,也和你电脑上的重启键是一个意思。
所以我们不讨论这种情况啦。没劲。
Perpetuum Mobile
永动机 我们再来看如下代码:
try {
while (true) {
System.out.println("I print here some useful information");
}
} finally {
System.out.println("Let me run");
}
这里的finlly块会执行吗?当然可能,就是在标准输出异常的时候。但是绝大部分情况答案仍然是不会。
Threads
什么是线程?我们都知道线程的执行流程可以被interrupted。
假设我们有一个线程正在执行一些东西,另外一个线程kill掉当前线程(此时他正要执行finally)。
还有一个场景是,如果两个线程之间有死锁,那么还是不会执行finally块的。
下面这段话仍然来自官方文档
...if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
所以这种情况下,我们可以把线程当做一个独立的程序来看:
Finally块肯定是会执行的。除了程序或者线程异常的终止了。
Finally we return
好了,根据上述的文字,我们了解了finally一定会被执行。但是你知道finally什么时候会被执行吗?
考虑如下代码:
int someFunc() {
try {
return 0;
} finally {
return 1;
}
}
这个返回值是多少呢? 返回值是1。因为finally一定会被执行。
考虑下面这段呢?
int someFunc() {
try {
throw new RuntimeException();
} finally {
return 1;
}
}
答案仍然是1。但是有个问题是,异常就被吞掉了。这个场景是一个非常有名的场景,叫做exception swallowing。这是一个非常危险示例,因为client的代码以为你会返回一个值或者抛出一个异常,但是你永远都只是返回一个值。
下面我们最后看一个类似的例子:
String deposit(int amount) throws DAOException {
try {
return dao.deposit(amount);
} finally {
return "OK";
}
}
dao.deposit会抛出一个受检的异常,导致客户端必须处理这个异常,但是呢,由于上面我们已经提到的原因,这个函数又永远返回OK,是不是有点淡淡的忧伤。
所以我们得到另外一个结论:
永远不要在finally里面使用return语句。
Instead of conclusion
很多程序员已经意识到finally的一些问题。但根据我们上面说的,只需要注意两点就可以避免犯错~
- Rule 1 Finally executes always, except the case where controlling program or thread was aborted.
- Rule 2 Never use return from finally block.
Java Magic. Part 3: Finally的更多相关文章
- Java Magic. Part 4: sun.misc.Unsafe
Java Magic. Part 4: sun.misc.Unsafe @(Base)[JDK, Unsafe, magic, 黑魔法] 转载请写明:原文地址 系列文章: -Java Magic. P ...
- Java Magic. Part 2: 0xCAFEBABE
Java Magic. Part 2: 0xCAFEBABE @(Base)[JDK, magic, 黑魔法] 转载请写明:原文地址 英文原文 系列文章: -Java Magic. Part 1: j ...
- Java Magic. Part 1: java.net.URL
Java Magic. Part 1: java.net.URL @(Base)[JDK, url, magic, 黑魔法] 英文原文 转载请写明:原文地址 系列文章: -Java Magic. Pa ...
- Magic Cast Method in Java Magic Trick In Java
https://www.atlassian.com/blog/archives/magic_trick_in_java https://www.gamlor.info/wordpress/2010/1 ...
- 【Java并发】详解 AbstractQueuedSynchronizer
前言 队列同步器 AbstractQueuedSynchronizer(以下简称 AQS),是用来构建锁或者其他同步组件的基础框架.它使用一个 int 成员变量来表示同步状态,通过 CAS 操作对同步 ...
- 【java编程】Java魔法类:Unsafe应用解析
转载来源:https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html 前言 Unsafe是位于sun.mis ...
- Java sun.misc.unsafe类
Java是一个安全的开发工具,它阻止开发人员犯很多低级的错误,而大部份的错误都是基于内存管理方面的.如果你想搞破坏,可以使用Unsafe这个类.这个类是属于sun.*API中的类,并且它不是J2SE中 ...
- Java并发编程-Unsafe实现原理与Unsafe应用解析
前言 Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别.不安全操作的方法,如直接访问系统内存资源.自主管理内存资源等,这些方法在提升Java运行效率.增强Java语言底层资源 ...
- sun.misc.unsafe
Java中大部分错误都是基于内存管理方面的.如果想破坏,可以使用Unsafe这个类. 实例化Unsafe: 下面两种方式是不行的 private Unsafe() {} //私有构造方法 @Calle ...
随机推荐
- IPv6调用java后端接口报错:java.net.SocketException: Protocol family unavailable
目前需求是java后端的接口需要支持IPv6.先确认linux机器已经绑定了IPv6: CMREAD-SV43 apache-tomcat/bin> ifconfig eth0 Link enc ...
- 【python】重定向输出
重定向的理解:就是把所要输出的结果输出到其他的地方.常用方法:"print >>",(若有其他方法后续补充) 举个例子: __author__ = 'paulwinfl ...
- Kibana 基础入门
原文地址:Kibana 基础入门 博客地址:http://www.extlight.com 一.前言 Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作.Kibana ...
- 安装Linux软件时没有图形界面的问题
Q: 现在Linux下的软件有很多也采用图形界面安装了:但有时候我们发现启动安装程序时本该出现图形界面时却出现了文本界面. A: 检查常用的图形函数库(最主要的自然是gtk, qt)是否已安装.尤其是 ...
- HA 部署wordpress
前提: 1.保证免密认证ssh 2.NTP时间是否同步: 3.保证防火墙,selinux关闭: 4.用户名互相能够解析:在hosts文件设置: 环境: 系统:centos6.8和centos7.2 I ...
- 转转转!!java基础一些静态代码块等知识点
一.代码块: 构造代码块------类中方法的外面:每次调用构造方法都执行: 静态代码块------类中方法的外面,括号前加上static:只执行一次,随着类的加载而执行: static代码块.构造代 ...
- [C#][MVC]DropDownListFor 默认值无法选中的 BUG
本文来自:https://www.cnblogs.com/craze/p/6124575.html 关于mvc中@Html.DropDownListFor和@Html.DropDownList默认值无 ...
- 9-16Jenkins-4节点
1.Jenkins-系统管理-全局安全配置,设置代理端口和协议类型,保存 2.Jenkins-系统管理-节点管理,建立节点 设置节点名称,节点工作目录.标签.用法.启动方式设置如下: 标签用于管理节点 ...
- [UE4]动画事件
在动画中添加事件通知,在动画蓝图中就可以使用这个事件通知: 在动画蓝图中可以使用“Try Get Pawn Owner”取得控制的角色实例 在Controller中,可以使用“Get Controll ...
- 样本稳定指数PSI
信用评定等级划分之后需要对评级的划分做出评价,分析这样的评级划分结果是否具有实用价值,即分析样本分布的稳定程度.样本分布稳定,则信用评定等级划分结果的实用价值就高.采用样本稳定指数( PSI )检验样 ...