Java開發中,正常狀況下,在執行了try代碼塊以後,finally中的代碼必定會執行。咱們實際開發也常常會利用這個特性,在finally中來執行一些特殊的操做,好比:釋放資源、釋放鎖等。java
demo線程
public class Finally { public static void main(String[] args) { try { //正常業務邏輯 System.out.println("I am try"); throw new RuntimeException("I am RuntimeExecption"); } catch (Exception e) { //異常處理 System.out.println("I am Exception -> " + e.getMessage()); } finally { //釋放資源等 System.out.println("I am Finally"); } } }
executecode
I am try I am Exception -> I am RuntimeExecption I am Finally
那麼是否是finally中的代碼必定會被執行呢?資源
其實否則,目前做者瞭解到有兩種狀況下,finally中的代碼不會被執行(不考慮try以前出現異常或者return的狀況,換言之,在try以前出現異常或者return時,try對應的finally中的內容不會被執行)開發
demoget
public class Finally { public static void main(String[] args) { try { //正常業務邏輯 System.out.println("I am try"); throw new RuntimeException("I am RuntimeExecption"); } catch (Exception e) { //異常處理 System.out.println("I am Exception -> " + e.getMessage()); System.exit(1);//異常關閉虛擬機 } finally { //釋放資源等 System.out.println("I am Finally"); } } }
execute虛擬機
I am try I am Exception -> I am RuntimeExecption
上面的代碼在出現了異常以後,使用System.exit(1)退出關閉虛擬機,finally中的代碼固然沒法執行。it
demoio
public class Finally { public static void main(String[] args) throws Exception { Thread thread = new Thread(new Runnable() { public void run() { try { //正常業務邏輯 System.out.println("I am try"); Thread.sleep(1000); } catch (Exception e) { //異常處理 System.out.println("I am Exception -> " + e.getMessage()); } finally { //釋放資源等 System.out.println("I am Finally"); } } }); thread.setDaemon(true); thread.start(); Thread.sleep(1000); System.out.println("end"); } }
executeclass
I am try end
使用setDaemon(true)方法來設置線程爲守護線程,從打印結果中能夠看到,守護線程中,try代碼塊中的代碼執行了,finally代碼塊未必執行。主要緣由是由於守護線程會隨着全部非守護線程的退出而退出。上述在主線程和守護線程中都設置sleep(1000)的緣由是怕線程run()方法還未開始執行主線程就退出了,這樣的話try代碼塊中的內容都不會執行。固然不是說守護線程中的finally代碼必定不會執行。
java中,若是想要執行try中的代碼以後,不容許再執行finally中的代碼,有如下兩種方式: