Java 中的異常
前段時間集合的整理真的是給我搞得心力交瘁啊,現在可以整理一些稍微簡單一點的,搭配學習 ~
突然想到一個問題,這些東西我之前就整理過,現在再次整理有什麼區別嘛?我就自問自答一下,可能我再次整理會看到不一樣的一面,會從原始碼和整體來看。其次,之前的整理都是在某個地方止步,可持續性較差,現在就盡力堅持住。因為還有你們再看 ~ 另外,歡迎各行各業的同學們給我投稿,讓大家都能互相瞭解,豈不是很棒!
進入正題,看看 Java 中的異常處理。當程式執行的時候沒有按照我們的意思執行,發生了一些不可言語的 bug 時,你打算怎麼搞?不管不問,還是主動出擊,而 Java 語言為此就準備了一套處理異常的類。
Throwable 類是 Java 語言中所有錯誤或異常的超類。只有當物件是此類(或其子類之一)的例項時,才能透過 Java 虛擬機器或者 Java throw 語句丟擲。類似地,只有此類或其子類之一才可以是 catch 子句中的引數型別。
兩個子類,Error 和 Exception,通常用於指示發生了異常情況。通常,這些例項是在異常情況的上下文中最新建立的,因此包含了相關的資訊(比如堆疊跟蹤資料)。Throwable 包含了其執行緒建立時執行緒執行堆疊的快照。還可以給出錯誤提示資訊。
Error 及其子類表示的是錯誤,是 JVM 本身出錯了,不能由程式控制,我們最主要就是看異常。
Exception 及其子類表示的是異常,異常又分為檢查異常和非檢查異常,這是在 javac 編譯器的角度進行分類的,檢查異常在我們編寫程式碼的時候會提示出來,我們必須要對其進行處理,處理方式有兩種,下面看。非檢查時異常對應於上圖中的 RuntimeException ,編譯的時候不報錯,在執行的時候才會出現。
在 Java 中處理異常有兩種思路,自己解決掉,乾淨利索或是拋給方法的呼叫者,就像你有事會找警察一樣,當然警察不一定能給你解決,就像是你丟擲的異常可能會被再次丟擲去一樣。最終會拋給 JVM ,然後程式掛掉。
自己處理主要是使用 try { } catch ( ) { } finally { } 語句塊,使用 try 包裹可能出現異常的程式碼,使用 catch 來捕獲可能出現的異常。最後 finally 語句塊是用來執行那些必須要執行的程式碼,比方說釋放資原始檔,關閉資料庫連線等操作。
有幾點需要說明一下:
1 可以有多個 catch 語句塊,但是捕獲異常的順序一定要注意,當異常出現時,只要被 catch 捕獲,則下面的 catch 不再執行。所以我們要把範圍小的異常種類或者說子類放在上面。
2 我們都聽過 finally 語句塊是一定會執行的,其實不是這樣的,當遇到 system.exit() 就不會再執行了,因為你強制退出 JVM 了。除此之外,確實是一定執行的。
3 只有 catch 塊才能處理異常,try 只是圈起範圍的作用,而 finally 塊是善後作用。
4 try catch finally 語句塊中的變數都是區域性變數,它們之間是不能共享的,待會看個例子。
另一種方式就是自己搞不定就使用 throws 丟擲去,拋給方法的呼叫者,讓它們去處理。在方法的宣告中新增語句 throws ,即可將檢查時異常丟擲,後續的處理就留給方法的 caller 吧!
上面都是在檢查異常發生時我們可以做的相應處理,若是執行時發生了異常,還有一種操作可以在程式碼執行的過程中手動的丟擲一個異常,使用 throw 關鍵字,例如這樣:
String name;if(name == "null"){ throw new IllegalArgumentException("姓名不能為空"); }
因為異常的產生是會形成連鎖反應,一旦有異常發生,所有的呼叫者都會發生異常,異常發生最開始的地方就是異常的丟擲點,丟擲點的異常會向 caller 轉移。所以在方法的重寫中,子類丟擲的異常型別一定要小於或等於父類的丟擲異常型別,不然,你想想,子類 throws 出去的異常太大,父類肯定接不住呀。
最後就是要看一個例子,來看一下 return 語句在語句塊中的應用。加深一下對異常處理的理解。
class Test { public int aaa() { int x = 1; try { return ++x; } catch (Exception e) { } finally { ++x; } return x; } public static void main(String[] args) { Test t = new Test(); int y = t.aaa(); System.out.println(y); } }
問:最後列印 y 是多少 ? 執行的過程是怎麼的 ?
結果是 2 ,過程卻可能不是那麼好解釋,在 try 語句中我們執行 ++x 然後就直接返回 2 ? 肯定不是,因為還要執行 finally 語句塊啊,所以 Java 規範規定,在存在 finally 塊時,會將 try 中的 return 放在一邊,而優先執行 finally 中的程式碼,但是已經得到的結果 2 可沒有丟了,而是存在了 try 塊中的本地變數表中,以備不時之需。
在執行 finally 塊之後,x 等於 3 ,一樣的還是會將 3 儲存在 finally 塊的本地變數表中,然後再回到 try 中進行 return 操作,此時,方法結束,返回的結果就是之前儲存在 try 塊本地變數表中的 2 。假如我們在 finally 塊中也有 return 語句,就會返回 3 而不再執行 try 中的 return 語句,然而 Java 規範不希望我們這麼做,因為 finally 語句塊的主要作用是為了釋放資源,關閉連線操作。
結合這個例子我們要明白,在每個語句塊中都會存在一個本地表量表,會儲存使用到變數的值,各個語句塊是分離開的,所以在執行 return 語句的時候,返回的是本地變數表中的變數。
在 finally 塊中使用 return 還有一個弊端,它會抑制 try 和 catch 中的異常的丟擲。看下面例子,在 try 塊中也是一樣的。
public static void main(String[] args) { int result; try{ result = foo(); System.out.println(result); //輸出100 } catch (Exception e){ System.out.println(e.getMessage()); //沒有捕獲到異常} //catch中的異常被抑制 @SuppressWarnings("finally") public static int foo() throws Exception { try { int a = 5/0; return 1; }catch(ArithmeticException amExp) { throw new Exception("我將被忽略,因為下面的finally中使用了return"); }finally { return 100; } } //try中的異常被抑制 @SuppressWarnings("finally") public static int bar() throws Exception { try { int a = 5/0; return 1; }finally { return 100; } }
總結
return 語句代表方法結束,但是遇到 finally 語句塊也是要等一等的。
無論 try 裡執行了 return 語句、break 語句、還是 continue 語句,finally 語句塊還會繼續執行,除非遇上了 system.exit() 。
finally 中不建議使用 return 語句的,釋放資源就好。
原文出處:https://www.cnblogs.com/YJK923/p/9528060.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2508/viewspace-2812575/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- java中的異常Java
- 聊聊Java中的異常(基礎篇)Java
- Java 中的異常處理機制Java
- Java異常的中斷和恢復Java
- Java異常Java
- Java 異常Java
- 異常JavaJava
- 【java】異常Java
- java 異常Java
- Java中的空指標異常 java.lang.NullPointerExceptionJava指標NullException
- Java中測試異常的多種方式Java
- Java中的異常處理最佳實踐Java
- Java 異常(二) 自定義異常Java
- Java checked異常和unchecked異常。Java
- java優雅的處理程式中的異常Java
- java之JAVA異常Java
- Java 異常處理中的種種細節!Java
- Java中的異常處理(隨堂筆記)Java筆記
- 揭曉Java異常體系中的祕密Java
- 對Java異常的理解Java
- Java中常見的異常Java
- java微服務的異常Java微服務
- Java中如何避免空指標異常Java指標
- Java中異常處理和設計Java
- java之異常Java
- jmu-Java-06異常-01-常見異常Java
- Java 異常表與異常處理原理Java
- Java中處理SocketException: Connection reset”異常的方法JavaException
- ORACLE中的異常(轉)Oracle
- 翻譯 | Java流中如何處理異常Java
- Java中如何處理空指標異常Java指標
- Java中的Exception拋異常對效能的影響 - BaeldungJavaException
- Java異常體系的探究Java
- Java--異常的學習Java
- Java的自定義異常類Java
- Java 異常(一) 異常概述及其架構Java架構
- Java基礎-異常Java
- Java 筆記《異常》Java筆記