finally块不被执行的情况总结


2019-08-03  22:23:02  by冲冲

finally块的作用

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

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

1. 未执行try块

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

 1 public class Test {
2 public static void main(String[] args) {
3 boolean flag = false;
4 if(flag) {
5 try {
6 System.out.println("enter try block");
7 } finally {
8 System.out.println("enter finally block");
9 }
10 }
11 }
12 }
13 /******************
14 控制台无输出
15 *******************/

2. System.exit()

System.exit()的作用是中止当前虚拟机,如果虚拟机被中止,程序也会被终止,finally代码块自然不会执行。

 1 public class Test {
2 public static void main(String[] args) {
3 try {
4 System.out.println("enter try block");
5 System.exit();
6 } finally {
7 System.out.println("enter finally block");
8 }
9 }
10 }
11 /*****************
12 控制台打印如下
13 enter try block
14 ******************/

3. try块陷入无限循环

 1 public class Test {
2 public static void main(String[] args) {
3 try {
4 while(true){
5 System.out.println("enter try block");
6 }
7 } finally {
8 System.out.println("enter finally block");
9 }
10 }
11 }
12 /*****************
13 完蛋
14 *****************/

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

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

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

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

 1 public class Test {
2 public static void main(String[] args) {
3 //main是一个非守护线程
4 Thread thread = new Thread(new Task());
5 thread.setDaemon(true); //设置thread为守护线程
6 thread.start();
7 TimeUnit.SECONDS.sleep(5); //阻塞5s.
8 }
9 }
10 class Task implements Runnable {
11 @Override
12 public void run() {
13 System.out.println("enter run()");
14 try {
15 System.out.println("enter try block");
16 } catch(InterruptedException e) {
17 System.out.println("enter catch block");
18 } finally {
19 System.out.println("enter finally block");
20 }
21 }
22 }
23 /*******************
24 控制台打印如下
25 enter run()
26 enter try block
27 enter try finally block
28 ********************/

上述代码,语句 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块被执行。

4. 其他迷惑性选项

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

 1 public class Test {
2 public static void main(String[] args) {
3 for (int i = 0; i < 5; i++) {
4 try {
5 if (i == 2) {
6 break;
7 }
8 } finally {
9 System.out.print(i);
10 }
11 }
12 }
13 }
14
15 /*************
16 输出结果:012
17 **************/

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

 1 public class Test {
2 public static void main(String[] args) {
3 for (int i = 0; i < 5; i++) {
4 try {
5 if (i == 2) {
6 return;
7 }
8 } finally {
9 System.out.print(i);
10 }
11 }
12 }
13 }
14
15 /*************
16 输出结果:012
17 **************/

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

 1 public class Test {
2 public static void main(String[] args) {
3 for (int i = 0; i < 5; i++) {
4 try {
5 if (i == 2) {
6 continue;
7 }
8 } finally {
9 System.out.print(i);
10 }
11 }
12 }
13 }
14
15 /*************
16 输出结果:01234
17 **************/

【JavaSE】finally块不被执行的情况总结的更多相关文章

  1. finally代码块不被执行的情况总结

    以前跟别人讨论finally关键字,我总是简单的说:“fianly代码块中的代码一定会执行,一般用来清除IO资源等非内存资源(内存资源由GC机制回收)”. 今天翻书发现了几种不会执行的情况,现在总结下 ...

  2. try-catch- finally块中, finally块唯一不执行的情况是什么?

    除非在try块或者catch块中调用了退出虚拟机的方法(即System.exit(1);),否则不管在try块.catch块中执行怎样的代码,出现怎样的情况,异常处理的finally块总是会被执行的 ...

  3. 触发Full GC执行的情况

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

  4. Java 静态语句块、语句块、构造函数执行顺序

    class Parent{ static String name = "hello"; { System.out.println("3 parent block" ...

  5. oracle 查看某session的历史执行sql情况

    1. 查看性能最差的前100sql SELECT * FROM ( SELECT PARSING_USER_ID EXECUTIONS,SORTS,COMMAND_TYPE,DISK_READS,sq ...

  6. Java静态语句块、语句块、构造方法执行顺序

    package com.imooc.practice; class Parent{ public Parent(){ System.out.println("Parent构造方法执行!&qu ...

  7. java学习(一)静态代码块 构造代码块 构造方法的执行顺序及注意问题

    今天我总结了一下java中静态代码块 构造代码块 构造方法的执行顺序及其注意问题 首先要知道静态代码块是随着类的加载而加载,而构造代码块和构造方法都是随着对象的创建而加载 当时做了这么一个小案例(想必 ...

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

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

  9. “全栈2019”Java异常第二十一章:finally不被执行的情况

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

随机推荐

  1. Git学习笔记02-配置

    安装好Git之后,做的就是需要配置Git了 第一步,配置自己的名称和邮箱 打开Git Bash 输入命令 git config --global user.name "用户名" g ...

  2. [AGC023D] Go Home 题解

    题目传送门 Solution 首先排除掉特殊情况:若 \(S\) 在两侧,肯定会顺序/逆序直接走完,答案就是边界减去出发点. 考虑到若 \(P_1\geq P_n\),那么显然 \(1\) 不到家 \ ...

  3. 《手把手教你》系列技巧篇(三十二)-java+ selenium自动化测试-select 下拉框(详解教程)

    1.简介 在实际自动化测试过程中,我们也避免不了会遇到下拉选择的测试,因此宏哥在这里直接分享和介绍一下,希望小伙伴或者童鞋们在以后工作中遇到可以有所帮助. 2.select 下拉框 2.1Select ...

  4. 【JAVA】【作业向】第一题:本学期一班级有n名学生,m门课程。现要求对每门课程的成绩进行统计:平均成绩、最高成绩、最低成绩,并统计考试成绩的分布律。

    1.预备知识:动态数组Array实现: 2.解题过程需要理解的知识:吧唧吧唧吧唧吧唧 不想做了 就用了最简单的方法 和c语言类似 java版本 `import java.util.Scanner; / ...

  5. DOM的本质 和 方法

    <JavaScript DOM编程艺术> 读书笔记 一句话解释DOM: DOM,即我们所看到的网页,其在浏览器背后的文档结构(树状分支结构),涵盖了每一个节点(称之为对象).可以通过JS等 ...

  6. 什么是Sprint计划?

    Sprint 计划是Scrum框架中的一个事件,团队将确定他们将在冲刺期间处理的产品积压项目,并讨论他们完成这些产品积压项目的初始计划. 团队可能会发现建立冲刺目标很有帮助,并以此为基础确定他们在冲刺 ...

  7. ScatterLayout:分散布局在py中的引用

    """ ScatterLayout:分散布局 """ from kivy.app import App from kivy.uix.scat ...

  8. 回应:Alpha深度评测

    零.说明 本篇博客是针对博客沉舟侧畔千帆过,病树前头万木春--对[题士]产品的深度测评与解析的回应,用以说明『题士』开发团队的观点.改进计划等 感谢HansBug.CookieLau助教及各位老师.测 ...

  9. 大闸蟹的 O O 战记

    一. 第四单元架构设计分析 第一次作业,UML类图 第一次作业的主要任务是完成对UML类图的解析并实现查询等操作,需要在课程组给定的框架中添加函数.对于UML类图,其存储是按照元素来存储的,其将所有的 ...

  10. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...