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