finally块的作用

通常用于处理善后工作。当try块里出现异常时,会立即跳出try块,到catch块匹配对应的异常,执行catch块里的语句。此时,可能在try块里存在打开的文件没关闭,连接的网络没断开,这部分资源是GC所不能自动处理的,所以finally的作用就是将它们及时释放回收。

finally块不被执行的情况,总共有3种:不进入try块、程序中止、线程中止(带finally块的是守护线程,其非守护线程都执行完毕)。

1. 未执行try块

对于try-catch-finally或者try-finally,如果不能进入try块,则finally块也无法进入。

public class Test {public static void main(String[] args) {boolean flag = false;if(flag) {try {System.out.println("enter try block");} finally {System.out.println("enter finally block");}}}
}/******************控制台无输出*******************/

2. System.exit()

public class Test {public static void main(String[] args) {try {System.out.println("enter try block");System.exit();} finally {System.out.println("enter finally block");}}
}
/*****************
控制台打印如下
enter try block
******************/

3. try块陷入无限循环

public class Test {public static void main(String[] args) {try {while(true){System.out.println("enter try block");}} finally {System.out.println("enter finally block");}}
}
/*****************完蛋*****************/

4. 守护(daemon)线程被中止时

Java线程分为两类,守护线程和非守护线程。当所有的非守护线程都终止时,无论守护线程存不存在,虚拟机都会kill掉所有的守护线程从而中止程序。

虚拟机中,执行main方法的线程就是一个非守护线程,垃圾回收则是另一个守护线程,main执行完,则程序中止,而不管垃圾回收线程是否中止。

所以,如果守护线程中存在finally代码块,那么当所有的非守护线程中止时,守护线程被kill掉,其finally代码块是不会执行的。

public class Test {public static void main(String[] args) {//main是一个非守护线程Thread thread = new Thread(new Task());thread.setDaemon(true); //设置thread为守护线程thread.start();TimeUnit.SECONDS.sleep(5); //阻塞5s.}
}
class Task implements Runnable {@Overridepublic void run() {System.out.println("enter run()");try {System.out.println("enter try block");} catch(InterruptedException e) {System.out.println("enter catch block");} finally {System.out.println("enter finally block");}}
}
/*******************
控制台打印如下
enter run()
enter try block
enter try finally block
********************/

上述代码,语句 TimeUnit.SECONDS.sleep(5); 会使main线程阻塞5秒,足够线程thread执行。

如果将该语句注释,非守护线程main线程执行完 thread.start(); 这行后,存在三种情况:①CPU时间片还是交给main线程,则非守护线程执行完毕,守护线程thread就会被终止,finally块不执行;②CPU时间片交给thread线程,但是thread线程刚执行完try块,就得交付时间片给main,main已经无语句执行,就会结束,导致守护线程thread也要结束,finally块不执行;③CPU时间片交付thread线程,thread线程完全执行,finally块被执行。

其他迷惑性选项

(1)当try块里面包含有break,该次try块结束后,finally块也会执行。

public class Test {public static void main(String[] args) {for (int i = 0; i < 5; i++) {try {if (i == 2) {break;}} finally {System.out.print(i);}}}
}/*************输出结果:012
**************/

(2)当try块里面包含有return,该次try块结束后,finally块也会执行。

public class Test {public static void main(String[] args) {for (int i = 0; i < 5; i++) {try {if (i == 2) {return;}} finally {System.out.print(i);}}}
}/*************输出结果:012
**************/

(3)当try块里面包含有continue,该次try块结束后,finally块也会执行。

public class Test {public static void main(String[] args) {for (int i = 0; i < 5; i++) {try {if (i == 2) {continue;}} finally {System.out.print(i);}}}
}/*************输出结果:01234
**************/

finally块不被执行的情况总结相关推荐

  1. (111)FPGA面试题-介绍Verilog 块语句fork-join执行过程

    1.1 FPGA面试题-介绍Verilog 块语句fork-join执行过程 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-介绍Verilog 块语句f ...

  2. (110)FPGA面试题-介绍Verilog块语句begin-end执行过程

    1.1 FPGA面试题-介绍Verilog块语句begin-end执行过程 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-介绍Verilog块语句beg ...

  3. java 中的静态变量,静态代码块,动态代码块,构造方法执行顺序的深入探究

    要想完全弄懂这个执行顺序,需要我们先了解几个概念. 首先是类加载与对象的构造,类加载就是在第一次调用这个类的时候jvm虚拟机会通过类加载器在一个叫做方法区的逻辑内存中将所要用到的类的信息存放在里边,其 ...

  4. 触发Full GC执行的情况 以及其它补充信息

    除直接调用System.gc外,触发Full GC执行的情况有如下四种.1. 旧生代空间不足旧生代空间只有在新生代对象转入及创建为大对象.大数组时才会出现不足的现象,当执行Full GC后空间仍然不足 ...

  5. 静态代码块、非静态代码块、构造函数执行顺序

    静态代码块.非静态代码块.构造函数执行顺序 /*** 类的实例化顺序,静态代码块.非静态代码块.构造函数.* @author MING*/ class Person {static String na ...

  6. Java普通代码块,构造代码块,静态代码块区别,执行顺序的代码实例

    Java普通代码块,构造代码块,静态代码块区别,执行顺序的代码实例 2018年05月08日 08:12:48 WJN不忘初心 阅读数:34 除了说普通代码块,静态代码块,构造代码块的执行顺序外,还有静 ...

  7. 静态代码块 构造代码块 构造方法的执行顺序

    今天我总结了一下java中静态代码块 构造代码块 构造方法的执行顺序及其注意问题 执行顺序: 静态代码块>构造代码块>构造方法体 首先要知道静态代码块是随着类的加载而加载,而构造代码块和构 ...

  8. java静态代码块和非静态代码块和构造函数执行顺序

    一.同类中静态代码块,非静态代码块,构造方法的执行顺序 1. 执行顺序:静态代码块-->非静态代码块-->构造方法. 程序在执行时,首先执行静态代码块,且只执行一次.接下来再创建对象时(n ...

  9. 【Java】静态代码块和非静态代码块什么时候执行?

    静态代码块和非静态代码块什么时候执行? 静态代码块随着类的加载而加载,非静态代码块随着对象的加载而加载 所以静态代码块再调用类的时候执行.非静态代码块创建对象时或者通过反射获取其类信息的时候执行

最新文章

  1. Maven-atguigu
  2. 计算机网络原理和OSI模型与TCP模型
  3. matlab求RMSECV,CARS 用于matlab模式识别(分类和回归)的特征变量提取方法 联合开发网 - pudn.com...
  4. hadoop jar包_计算机毕业设计中hadoop上运行Java程序
  5. flask 上传头像
  6. 开始使用ASP.NET核心运行状况检查
  7. 一步步实现SDDC-双节点VSAN部署
  8. 开发健康状态监控接口
  9. C语言杨辉三角形代码
  10. 第10周项目1 二叉树算法库
  11. 什么是机器人编程课程
  12. 四年运维人员的一些唠叨
  13. WhatsApp电脑版和WhatsApp网页版区别?
  14. CCRC信息安全服务资质分类及申请流程
  15. ios和android前景!阿里面试100%会问到的JVM,架构师必备技能
  16. C语言学习笔记(九)
  17. SEO(什么是seo,如何优化seo)
  18. C/C++中内存区域划分大总结
  19. 下拉选择框插件chosen
  20. JNI(二) - 如何生成so并暴露给第三方使用

热门文章

  1. bzoj#3456. 城市规划
  2. P2305 [NOI2014]购票
  3. CodeForces - 616D Longest k-Good Segment
  4. Matlab快速入门
  5. 牛客题霸 [括号序列] C++题解/答案
  6. 数据结构题(莫队算法)
  7. CF1153F-Serval and Bonus Problem【dp,数学期望】
  8. P1993-小K的农场【差分约束,SPFA】
  9. 牛客练习赛 63 F-牛牛的树行棋
  10. Namomo Fish(Easy) Round 1