異常是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
,最後返回12
。3d
不知道你發現規律沒有,下面再舉個例子你就更清晰了。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 塊的真正運行時機了:
return
。return
以前執行。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;
}
複製代碼