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. 其他css属性和特性

    其他css属性和特性 设置元素的颜色和透明度 下表列出了这些属性. 颜色相关属性 属 性 说 明 值 color 设置元素的前景色 <颜色> opacity 设置颜色的透明度 <数值 ...

  2. TCP服务器和客户端_Socket编程

    TCP服务器 服务器启动文件 1 import java.io.IOException; 2 import java.net.ServerSocket; 3 import java.net.Socke ...

  3. appium操作安卓应用所需要的数据准备

    操作系统.系统版本如下所示: desired_caps={} desired_caps["platformName"]="Android" desired_ca ...

  4. Python常用加密解密算法

    MD5加密 简介 这是一种使用非常广泛的加密方式,不可逆的,常见16位和32位一般都是md5 实现 import hashlib data = '你好' print(hashlib.md5(data. ...

  5. C#特性知识图谱-二、事件

    C#特性知识图谱-二.事件 二.事件 在事件驱动的软件系统中,符合某种预设条件的情形出现是,一个事件就会被触发. 2.1 事件三要素 事件源:激发事件的对象 事件信息:事件本身说携带的信息 事件响应者 ...

  6. Linux上传下载神器之 lrzsz

    在开发的过程中,经常遇到 需要在 Linux 和 Windows 之间上传下载文件的情况 这时,一般都是使用 FTP 或者 WinSCP 工具进行上传下载, 虽然也能解决问题,但是这些工具需要在本地安 ...

  7. 在Excel中,不利用任何第三方工具,生成二维码

    有同事提需求,要批量生成二维码.谈了之后,我觉得可以做个excel文件,把要打印的内容放进去,然后给每行数据生成一个二维码.下一步就要在Excel里面生成二维码.问了一下度娘,貌似都得利用一些第三方工 ...

  8. BUAA2020软工作业(一)——谈谈我和计算机的缘分

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! 我在这个课程的目标是 进一步提高自己的编码能力,工程能力 这个作业在哪个具体方 ...

  9. elasticsearch入门(简单的crud操作)

    记录一下,elasticsearch从创建索引到插入数据的一个crud操作. 一.创建索引 curl -XPUT "http://192.168.99.1:9200/productindex ...

  10. 这一篇 K8S(Kubernetes)我觉得可以了解一下!!!

    点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 什么是Kubernetes? Kubernetes 是Google开源的分布式容器管理平台,是为 ...