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

1.finally的含义

finally的真正含义是指从try代码块出来才一定会执行相应的finally代码块。

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

上述代码,flag为false,没有进入try代码块,对应的finally自然也不会执行。

2.System.exit()

System.exit()的作用是中止当前虚拟机,虚拟机都被中止了,finally代码块自然不会执行。

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

上述代码,进入foo()方法后再进入try代码块,但是在进入finally代码块之前调用了System.exit()中止虚拟机, finally代码块不会被执行。

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

java线程分为两类,守护线程和非守护线程。当所有的非守护线程中止时,不论存不存在守护线程,虚拟机都会kill掉守护线程从而中止程序。 虚拟机中,执行main方法的线程就是一个非守护线程,垃圾回收则是另一个守护线程,main执行完,程序就中止了,而不管垃圾回收线程是否中止。 所以,如果守护线程中存在finally代码块,那么当所有的非守护线程中止时,守护线程被kill掉,其finally代码块是不会执行的。

public class Test {
public static void main(String[] args) {
Thread t = new Thread(new Task());
t.setDaemon(true); //置为守护线程
t.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException("the "+Thread.currentThread().getName()+" has been interrupted",e);
}
}
}
class Task implements Runnable {
@Override
public void run() {
System.out.println("enter run()");
try {
System.out.println("enter try block");
TimeUnit.SECONDS.sleep(5); //阻塞5s
} catch(InterruptedException e) {
System.out.println("enter catch block");
throw new RuntimeException("the "+Thread.currentThread().getName()+" has been interrupted",e);
} finally {
System.out.println("enter finally block");
}
}
}
/*******************
控制台打印如下
enter run()
enter try block
********************/

上述代码,main()执行完,非守护线程也就结束了,虽然线程t处于阻塞状态,但由于其是守护线程,所以程序仍会中止。 而且,即使其进入了try代码块,finally代码块也不会被执行。

总结

finally代码块并非一定执行,在不进入try代码块或者程序被中止时就不会执行。

引用

1.《Java编程思想》

finally代码块不被执行的情况总结的更多相关文章

  1. 【JavaSE】finally块不被执行的情况总结

    finally块不被执行的情况总结 2019-08-03  22:23:02  by冲冲 finally块的作用 通常用于处理善后工作.当try块里出现异常时,会立即跳出try块,到catch块匹配对 ...

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

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

  3. 【转】java静态代码块和构造方法执行顺序

    先看看下面几个类,然后判断它们的输出public class A { static{System.out.print(1);}public A(){System.out.print(2);}} pub ...

  4. Java面试题 静态代码块 构造代码块 构造方法 的执行顺序

    JAVA中的静态代码块 构造代码块 构造方法执行顺序: 静态代码块(类加载时执行)>>构造代码块>>构造方法 下面展示一个简单的例子,推荐大家动手运行一遍: public cl ...

  5. java面试基础题------》Java 中的父子类静态代码块,代码块,构造方法执行顺序

    4.指出下面程序的运行结果. class A { static { System.out.print("1"); } public A() { System.out.print(& ...

  6. Java静态代码块、代码块及构造函数执行顺序

    根据以下程序进行分析 定义一个父类 package sas.LearnJava; public class ExcuteOrderTest { { System.out.println("我 ...

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

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

  8. 由阿里巴巴一道笔试题看Java静态代码块、静态函数、动态代码块、构造函数等的执行顺序

    一.阿里巴巴笔试题: public class Test { public static int k = 0; public static Test t1 = new Test("t1&qu ...

  9. 关于finally代码块是否一定被执行的问题

    一般来说,只要执行了try语句,finally就会执行 但是,有以下几种情况需要特殊考虑 具体例子看链接  点击这里 第一点 try代码块没有被执行,意思就是错误在try代码块之前就发生了. 第二点 ...

随机推荐

  1. 4.vue引入axios同源跨域

    前言: 跨域方案有很多种,既然我们用到了Vue,那么就使用vue提供的跨域方案. 解决方案: 1.修改HttpRequestUtil.js import axios from 'axios' expo ...

  2. eclipse环境Dynamic web module version 3.1版本的进步,简化Dynamic web object 中Servlet类的配置,不用web.xml配置<Servlet>

    eclipse环境Dynamic web module version 3.1版本之前,Dynamic web object 中Servlet类的配置,要在web.xml 配置<Servlet& ...

  3. 微信小程序清除默认样式

    1.清除button的默认样式 button::after{border:none;}input{outline:none;border:none;list-style: none;}

  4. PHP生成ZIP压缩文件

    PHP生成ZIP压缩文件 /* * 生成zip压缩文件 * $sourceDir:被压缩的文件夹或文件 * $outFileName:输出的压缩文件名称 * */ function createZip ...

  5. tcl之控制流-break/continue

  6. Laravel5.5.x集成Swagger (L5-Swagger) 只讲Laravel5.5.x的集成,laravel其他版本请自行研究或参考github上的说明

    --------上图 截取自Github 官网上的安装参考----------------------------------------------------------------------- ...

  7. ERROR 1005 (HY000): Can't create table 'students.#sql-d9

    今天在创建外键的时候出现以下错误        ERROR 1005 (HY000): Can't create table 'students.#sql-d99_3' (errno: 150) 格式 ...

  8. 15 Django组件-中间件

    中间件 中间件的概念 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好 ...

  9. 6,Flask 中内置的 Session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  10. spring里面的context:component-scan

    原文:http://jinnianshilongnian.iteye.com/blog/1762632 component-scan的作用的自动扫描,把扫描到加了注解Java文件都注册成bean &l ...