finally代码块不被执行的情况总结
以前跟别人讨论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代码块不被执行的情况总结的更多相关文章
- 【JavaSE】finally块不被执行的情况总结
finally块不被执行的情况总结 2019-08-03 22:23:02 by冲冲 finally块的作用 通常用于处理善后工作.当try块里出现异常时,会立即跳出try块,到catch块匹配对 ...
- java学习(一)静态代码块 构造代码块 构造方法的执行顺序及注意问题
今天我总结了一下java中静态代码块 构造代码块 构造方法的执行顺序及其注意问题 首先要知道静态代码块是随着类的加载而加载,而构造代码块和构造方法都是随着对象的创建而加载 当时做了这么一个小案例(想必 ...
- 【转】java静态代码块和构造方法执行顺序
先看看下面几个类,然后判断它们的输出public class A { static{System.out.print(1);}public A(){System.out.print(2);}} pub ...
- Java面试题 静态代码块 构造代码块 构造方法 的执行顺序
JAVA中的静态代码块 构造代码块 构造方法执行顺序: 静态代码块(类加载时执行)>>构造代码块>>构造方法 下面展示一个简单的例子,推荐大家动手运行一遍: public cl ...
- java面试基础题------》Java 中的父子类静态代码块,代码块,构造方法执行顺序
4.指出下面程序的运行结果. class A { static { System.out.print("1"); } public A() { System.out.print(& ...
- Java静态代码块、代码块及构造函数执行顺序
根据以下程序进行分析 定义一个父类 package sas.LearnJava; public class ExcuteOrderTest { { System.out.println("我 ...
- try-catch- finally块中, finally块唯一不执行的情况是什么?
除非在try块或者catch块中调用了退出虚拟机的方法(即System.exit(1);),否则不管在try块.catch块中执行怎样的代码,出现怎样的情况,异常处理的finally块总是会被执行的 ...
- 由阿里巴巴一道笔试题看Java静态代码块、静态函数、动态代码块、构造函数等的执行顺序
一.阿里巴巴笔试题: public class Test { public static int k = 0; public static Test t1 = new Test("t1&qu ...
- 关于finally代码块是否一定被执行的问题
一般来说,只要执行了try语句,finally就会执行 但是,有以下几种情况需要特殊考虑 具体例子看链接 点击这里 第一点 try代码块没有被执行,意思就是错误在try代码块之前就发生了. 第二点 ...
随机推荐
- Java框架 面试题总结
一. Struts1.x 4 1. struts1优缺点,为什么要使用struts1 4 2. Struts1核心组件 4 3. Strust1请求处理流程 工作原理 4 4. Struts1线程安 ...
- 当Java遇见了Html--Jsp九大内置对象篇
jsp内置对象对象是web容器创建的一组对象,不使用new关键词久可以使用的内置对象. 九大内置对象包括以下: out --JspWriter request --ServletRequest rep ...
- ethereum(以太坊)(十二)--应用(一)__集资(构造函数/映射)
pragma solidity ^0.4.4; contract funder{ //0xca35b7d915458ef540ade6068dfe2f44e8fa733c //0x14723a09ac ...
- scrapy--多爬虫
大家好,我胡汉三又回来了!!!开心QAQ 由于最近一直在忙工作的事,之前学的一些爬虫知识忘得差不多了,只能再花多一些时间来回顾,否则根本无法前进.所以在这里也像高中老师那样提醒一下大家,--每天晚上花 ...
- iar注释快捷键
选中多行后注释快捷键:Ctrl+K 取消多行注释快捷键:Ctrl+Shift+K
- 第五章 标准I/O
5.1 引言 本章说明标准 I/O 库.因为不仅在 UNIX 上,而且在很多操作系统上都实现了此库,所以它由 ISO C 标准说明. 标准 I/O 库处理很多细节,例如缓冲区分配,以优化长度执行 I/ ...
- ISCSI网络存储
ISCSI(iSCSI,Internet Small Computer System Interface) iSCSI技术实现了物理硬盘设备与TCP/IP网络协议的相互结合,使得用户可以通过互联网方便 ...
- shell判断文件是否存在[转]
原文出处: http://canofy.iteye.com/blog/252289 shell判断文件,目录是否存在或者具有权限 #!/bin/sh myPath="/var/log/htt ...
- C#中接口与抽象类的区别
接口与抽象类是面试中经常会考到的点,容易混淆.首先了解下两者的概念: 一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类 ...
- 玩转Linux之pwd命令
玩转Linux之pwd命令 你有没有遇到过需要知道当前所在目录却无从得知?有没有想要复制出当前所在目录层次却不知如何下手?俗话说有困难找警察,想知道目录层次自然要找pwd了.那么问题来了: 什么是pw ...