首页 / 知识
Java语言中,finally一定会执行吗?
2023-04-11 16:24:00

简介
我们都知道,finally 作为异常处理的一部分,它只能紧跟在try/catch语句后,附带一个语句块,表示这段语句,“在正常情况下”,最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。那么在我们的应用在运行中,一定会运行finally代码块吗?其实不是的,有以下几种情况我们的finally代码块是不会运行的。
finally 代码块不会运行的情况
情况一:代码流程并未进入try语句块
这也是最好理解的情况,如果代码流程不进入try代码块,则相应的catch和finally代码块自然不会执行。
public static void main(String[] args) {
int i = 0;
System.out.println("enter main block");
boolean flag = false;
if (flag) {
try {
System.out.println("enter try block");
i = i / i;
} catch (Exception e) {
System.out.println("enter catch block");
}finally {
System.out.println("enter finally block");
}
}
}
运行结果为:
enter main block
情况二: 使用了 System.exit(int) 退出程序
在进入try或catch块后,使用了 System.exit(int) 退出程序。
public static void main(String[] args) {
int i = 0;
System.out.println("enter main block");
try {
System.out.println("enter try block");
System.exit(0);
i = i / i;
} catch (Exception e) {
System.out.println("enter catch block");
} finally {
System.out.println("enter finally block");
}
}
或
public static void main(String[] args) {
int i = 0;
System.out.println("enter main block");
try {
System.out.println("enter try block");
i = i / i;
} catch (Exception e) {
System.exit(0);
System.out.println("enter catch block");
} finally {
System.out.println("enter finally block");
}
}
运行结果为:
enter main block
enter try block
1
2
但是呢,如果 System.exit(int) 在try代码块异常语句之后, finally 还是会被执行,因为已经没有机会执行 System.exit(int) ,程序已经退出了,比如:
public static void main(String[] args) {
int i = 0;
System.out.println("enter main block");
try {
System.out.println("enter try block");
i = i / i;
System.exit(0);
} catch (Exception e) {
System.out.println("enter catch block");
} finally {
System.out.println("enter finally block");
}
}
运行结果为:
enter main block
enter try block
enter catch block
enter finally block
情况三:程序所在的线程死亡
在当前线程死亡的情况下,finally里的语句也不会执行,比如干扰中断,或者程序外部kill该线程,或者是意外中止。
public static void main(String[] args) {
int i = 0;
System.out.println("enter main block");
try {
System.out.println("enter try block");
// 模拟执行任务10s,然后在执行任务过程中杀死该线程
Thread.sleep(10 * 1000);
i = i / i;
} catch (Exception e) {
System.out.println("enter catch block");
} finally {
System.out.println("enter finally block");
}
这里在休眠里,用kill命令,杀死该线程,模拟非正常退出,最后运行结果为:
enter main block
enter try block
这里值得注意的是,我们常常在try语句块里获取了一些临界资源,然后finally语句块里释放该资源。此时,如果正常获得取资源后,程序非正常中断,则我们并未正常释放该资源,就会导致资源可能会被无限占用,所以这里要考虑一下其它的解决方法,比如给资源设置一个使用时间等,到期自动收回。
情况四:其它非正常退出
还有其它非正常退出(道理同上,就不演示了),也会导致finally代码块不执行,比如物理关闭电源,关闭 CPU等。这些其实在开发生产环境中是常有出现的,比如在开发中,某一台服务器获取锁后,不小心断电或宕机了(未成功释放锁),然后导致别的机器也不能获得到锁(如果锁无时间限制),最终导致出现系统型的问题。完事以后,你们开发也不知道发生了什么事,就把所有服务都重启了一次,解决了问题,最后说一句:“啊!还是重启大法好”。
|
最新内容
相关内容
编写一个简单的游戏来学习 Python
编写一个简单的游戏来学习 Python,数字,标准,概念,名称,异常,软件,基础知识,培训,通用,流程,通过编写一个“猜数字”游戏来探索Python(和其他如何杀死一个Python线程
如何杀死一个Python线程,状态,线程,代码,标准,意外,工作,控制权,培训,事件,结束,我经常被问到如何杀死一个后台线程,这个问题的答案让很多人不用Python开发一个简单的猜数字游戏
用Python开发一个简单的猜数字游戏,数字,代码,培训,官网,设备,程序,玩家,注释,内容,游戏,本文介绍如何使用Python制作一个简单的猜数字游戏。Python的英语搭配助手应用开发研究
Python的英语搭配助手应用开发研究,信息,设计,网站,在线,代码,环境,数据,分析,时间,培训,基于Python自带的GUI工具包Tkinter来实现窗口视窗设Python变量的类型(弱类型语言)
Python变量的类型(弱类型语言),检测,代码,数据,培训,类型,变量,语言,赋值,数字型,字符串,在强类型的编程语言中,定义变量时要指明变量的类型,而Python可执行文件和模块
Python可执行文件和模块,标准,培训,模块,文件,属性,上面,内容,变量,函数,源码,python源代码文件按照功能可以分为两种类型:用于执行的可执行程python unittest控制用例的执行顺
python unittest控制用例的执行顺序,名字,交易,培训,方法,顺序,测试,方式,功能,订单,接口,为什么要进行顺序控制呢?使用过testng的同学就知道使用Python执行系统命令方法
使用Python执行系统命令方法,系统,信息,培训,标准,命令,方法,模块,操作,终端,中文,Python是一款操作简单的编程语言,内置丰富的库,能够很容易的python支持r语言吗?
python支持r语言吗?,代码,名称,培训,官网,第一,语言,对象,字符串,方法,后缀,python中可以支持r语言。python提供了一个模块rpy2,可以较好地完python中有跳转语句吗?
python中有跳转语句吗?,培训,语句,桔子,继续,嵌套,条件下,剩余,表示,结果,示例,python中有跳转语句,分别是continue语句,跳过本次循环;break语找不出python的语法错误该如何解决
找不出python的语法错误该如何解决?,代码,分析,项目,培训,错误,语法错误,结果,文件,语法,环节,python是一种解释型语言,在开发中,没有了编译这python如何调用另一个文件夹中的内
python如何调用另一个文件夹中的内容?,系统,培训,文件,模块,内容,路径,函数,所在,前缀,语句,python中调用另外一个文件夹中的内容:1、同一文件