java finally可以省略,关于java的10个谎言之finally

经常在面试题中会看到:exit、finally、return的提问,这也是考察个人的基础知识。

一般(注意我的措辞‘一般’)我们都知道exit()是退出虚拟机,那么一旦调用了exit,则不管什么

return 、finally统统忽略不计,但前段时间看到了一篇博文“关于java的10个谎言”(搜了一下,好多

地方都有,也不知道谁是"首发"),这里要小记一下第一个问题(System.exit(0)会跳过finally的执

行?)的思考。

1、三者一般执行顺序

a、return,表示方法执行返回或者结束方法运行,其实就是方法退出栈执行

b、exit(0) ,退出虚拟机(一般认为就立马结束虚拟机生命)

c、finally ,一般直接跟在try块或者catch块后面,在try或catch语句块中控制转移语句之前执行。

eixt,很好理解,那return与finally呢?可以这样通俗的理解:

在面向对象程序执行过程其实就是各种对象之间通信,对象之间的通信不就是方法调用吗,是的,所以程序执行就是一个个方法的运行,所有方法运行完了,程序也就结束了,而finally只是一个语句,那么他势必是属于某个方法的(事实是,编译器在编译finally块的时候也只是这么做的),而return是方法的结束语句,这样一来,二者就转化为顺序执行了――先finally后return(方法都要退出栈了,还不执行finally,等待何时 ?)。

其实上面的只是帮助理解,本质上,finally块在虚拟机编译处理的时候,会将finally块的语句插入到try

或者catch语句块中的控制转移语句之前,而return就是控制转移语句之一,所以,当二者同时出现

时,finally语句块会被编译器插如到return之前 。

2、System.exit(0)会跳过finally的执行?  真的吗?

上面对三者的执行顺序做了简单总结,但是运行如下代码试试,看exit后为啥还执行finally?public static void main(String[] args) {

System.setSecurityManager(new SecurityManager(){

@Override

public void checkExit(int status) {

throw new ThreadDeath();

}

});

try {

System.exit(0);

} finally{

System.out.println("in finally block ");

}

}

执行结果可能颠覆了前面说的:exit后其他都不执行,其实,前面说的是一般情况,而且99%的情况都

是那样的顺序,只是上面的代码耍了小心机(或者说我们没仔细探究exit方法)。

上面代码之所以会输出“in finally block”,是因为前面设置的SecurityManager中覆盖了checkExit方法,导致虚拟机并没有退出,为什么呢,请看分析:

其实,这一切都是因为exit方法的实现过程,以下片段为Runtime 类中exit方法源码:public void exit(int status) {

SecurityManager security = System.getSecurityManager();

if (security != null) {

security.checkExit(status);

}

Shutdown.exit(status);

}

main方法开始自上而下执行,首先设置了一个安全管理器实例,接着调用System.exit(0) ,调用时执行上面的exit方法,运行环境获取到了我们自定义安全管理器,并开始调用覆盖的方法,checkExit ,但checkExit方法抛出了error(不是exception,请看ThreadDeath类),导致exit的中Shutdown.exit()调用失败,从而导致虚拟机并没有退出,那么finally当然要执行了。

经此,看来我们以后在学习过程中一定要看一手资料,多看细节实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值