finally块不被执行的情况总结
finally塊的作用
通常用于處理善后工作。當(dāng)try塊里出現(xiàn)異常時(shí),會(huì)立即跳出try塊,到catch塊匹配對(duì)應(yīng)的異常,執(zhí)行catch塊里的語(yǔ)句。此時(shí),可能在try塊里存在打開的文件沒關(guān)閉,連接的網(wǎng)絡(luò)沒斷開,這部分資源是GC所不能自動(dòng)處理的,所以finally的作用就是將它們及時(shí)釋放回收。
finally塊不被執(zhí)行的情況,總共有3種:不進(jìn)入try塊、程序中止、線程中止(帶finally塊的是守護(hù)線程,其非守護(hù)線程都執(zhí)行完畢)。
1. 未執(zhí)行try塊
對(duì)于try-catch-finally或者try-finally,如果不能進(jìn)入try塊,則finally塊也無法進(jìn)入。
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");}}} }/******************控制臺(tái)無輸出*******************/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");}} } /***************** 控制臺(tái)打印如下 enter try block ******************/3. try塊陷入無限循環(huán)
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. 守護(hù)(daemon)線程被中止時(shí)
Java線程分為兩類,守護(hù)線程和非守護(hù)線程。當(dāng)所有的非守護(hù)線程都終止時(shí),無論守護(hù)線程存不存在,虛擬機(jī)都會(huì)kill掉所有的守護(hù)線程從而中止程序。
虛擬機(jī)中,執(zhí)行main方法的線程就是一個(gè)非守護(hù)線程,垃圾回收則是另一個(gè)守護(hù)線程,main執(zhí)行完,則程序中止,而不管垃圾回收線程是否中止。
所以,如果守護(hù)線程中存在finally代碼塊,那么當(dāng)所有的非守護(hù)線程中止時(shí),守護(hù)線程被kill掉,其finally代碼塊是不會(huì)執(zhí)行的。
public class Test {public static void main(String[] args) {//main是一個(gè)非守護(hù)線程Thread thread = new Thread(new Task());thread.setDaemon(true); //設(shè)置thread為守護(hù)線程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");}} } /******************* 控制臺(tái)打印如下 enter run() enter try block enter try finally block ********************/上述代碼,語(yǔ)句 TimeUnit.SECONDS.sleep(5); 會(huì)使main線程阻塞5秒,足夠線程thread執(zhí)行。
如果將該語(yǔ)句注釋,非守護(hù)線程main線程執(zhí)行完 thread.start(); 這行后,存在三種情況:①CPU時(shí)間片還是交給main線程,則非守護(hù)線程執(zhí)行完畢,守護(hù)線程thread就會(huì)被終止,finally塊不執(zhí)行;②CPU時(shí)間片交給thread線程,但是thread線程剛執(zhí)行完try塊,就得交付時(shí)間片給main,main已經(jīng)無語(yǔ)句執(zhí)行,就會(huì)結(jié)束,導(dǎo)致守護(hù)線程thread也要結(jié)束,finally塊不執(zhí)行;③CPU時(shí)間片交付thread線程,thread線程完全執(zhí)行,finally塊被執(zhí)行。
其他迷惑性選項(xiàng)
(1)當(dāng)try塊里面包含有break,該次try塊結(jié)束后,finally塊也會(huì)執(zhí)行。
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);}}} }/*************輸出結(jié)果:012 **************/(2)當(dāng)try塊里面包含有return,該次try塊結(jié)束后,finally塊也會(huì)執(zhí)行。
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);}}} }/*************輸出結(jié)果:012 **************/(3)當(dāng)try塊里面包含有continue,該次try塊結(jié)束后,finally塊也會(huì)執(zhí)行。
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);}}} }/*************輸出結(jié)果:01234 **************/總結(jié)
以上是生活随笔為你收集整理的finally块不被执行的情况总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 毫秒延时(linux 秒 毫
- 下一篇: JVM内存结构分析:为什么需要S0和S1