不知道大家有沒有問過自己,finally方法會在什麼時候不執行呢???有些人可能會一臉懵逼的說:怎麼可能會不執行呢,那我們下面來看看finally到底會不會不執行。
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代碼塊或者程序被中止時就不會執行。所以寫代碼一定不要想當然,可能你認爲絕對不會執行的代碼,有時候它還真會執行,什麼時候我們都要帶着批判思維(熟話說:帶腦子)進行程序的開發。
想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~
林老師帶你學編程:https://wolzq.com