Java異常系列之finally的真正運行時機

異常是Java核心中很是重要的一個概念,但卻很容易被你們忽略,這個系列咱們會深刻講一下這個話題。學完這個系列,相信會讓你對異常體系以及異常的各類使用場景,瞭如指掌,成爲你職業進階的必備技能。java

名稱 狀態
finally 的真正運行時機 已完成
try-with-resources 語句 已完成
Java 異常體系 創做中...
catch 中的異常參數 創做中...
Java 異常鏈 創做中...
SpringMVC 中的異常處理 創做中...
自定義 SpringMVC 的異常處理鏈 創做中...

在以前的 Java語法糖 : 使用 try-with-resources 語句安全地釋放資源 一文中,咱們介紹瞭如何經過 try-with-resources 語句來代替醜陋的 finally 塊。安全

但 try-with-resources 語句僅僅適用於自動關閉資源,有些場景下咱們須要不管一段代碼發生異常與否,都須要執行另一段代碼,這個時候就須要使用 finally 塊了。bash

若是有人問你 發生異常之後 finally 塊的內容何時會執行?你也許會堅決果斷地回答:固然是執行完 catch 塊的內容之後執行了。post

但有時候你的回答也許無法這麼幹脆,好比下面這個例子。ui

當在 catch 塊和 finally 塊同時return的時候,到底會return什麼呢?spa

public static int testFinally1() {
    try {
        Integer.parseInt("exception here");
    } catch (Exception e) {
        System.out.println("catch block 1");
        return 11;
    } finally {
        System.out.println("finally block 1");
        return 12;
    }
}
複製代碼

事實上,即便 catch 塊有return語句, finally 塊必然執行的邏輯仍是成立的。上面的方法,return的是12。先輸出catch block 1,而後輸出finally block 1,最後返回123d

不知道你發現規律沒有,下面再舉個例子你就更清晰了。code

public static int testFinally3() {
    try {
        System.out.println("start");
        Integer.parseInt("testFinally3");
        System.out.println("never run");
    } catch (Exception e) {
        System.out.println("catch block 3");
        return iamReturn();
    } finally {
        System.out.println("finally block 3");
    }
    return 31;
}

public static int iamReturn() {
    System.out.println("return block");
    return 666;
}
複製代碼

思考一下執行這個方法會分別輸出和返回什麼?cdn

先彆着急看答案,根據咱們以前發現的規律, finally 塊必然執行,而 catch 塊的非return部分須要在 finally 塊以前執行。那麼最終返回的應該是666資源

答案確實如此。下面是控制檯輸出的順序:

start
catch block 3
return block
finally block 3
複製代碼

由此,咱們能夠總結 finally 塊的真正運行時機了:

  1. finally 塊必然執行,不論發生異常與否,也不論在 finally 以前是否有return
  2. 無論在 try 塊中仍是在 catch 塊中包含 return,finally 塊老是在 return 以前執行。
  3. 若是 finally 塊中有return,那麼 try 塊和 catch 塊中的 return 就沒有執行機會了。

若是你真的理解了finally 塊的真正運行時機,那麼請思考一下,下面程序的返回值是21仍是22,歡迎留言討論。

public static int testFinally2() {
    try {
        System.out.println("start");
        return 21;
    } catch (Exception e) {
        System.out.println("catch block 2");
    } finally {
        System.out.println("finally block 2");
    }
    return 22;
}
複製代碼

Wechat-westcall
相關文章
相關標籤/搜索