1. 程式人生 > >【java基礎之異常】死了都要try,不淋漓盡致地catch我不痛快!

【java基礎之異常】死了都要try,不淋漓盡致地catch我不痛快!

@[toc] # 1、異常 ## 1.1 異常概念 **異常** :簡單說就是不正常執行,最終導致JVM的非正常停止。 在Java等面向物件的程式語言中,異常本身是一個類,產生異常就是建立異常物件並丟擲了一個異常物件。Java處理異常的方式是中斷處理。 > 異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生位元組碼檔案,根本不能執行. ## 1.2 異常體系 異常機制其實是幫助我們**找到**程式中的問題,異常的根類是`java.lang.Throwable`,其下有兩個子類:`java.lang.Error`與`java.lang.Exception`,平常所說的異常指`java.lang.Exception`。 ![\[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-A0NGTCB9-1570323592244)(img\異常體系.png)\]](https://img-blog.csdnimg.cn/20191006090230495.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) **Throwable中的常用方法:** 1、 `public void printStackTrace()`:列印異常的詳細資訊。 *包含了異常的型別,異常的原因,還包括異常出現的位置,在開發和除錯階段,都得使用printStackTrace。* 2、 `public String getMessage()`:獲取發生異常的原因。 *提示給使用者的時候,就提示錯誤原因。* 3、 `public String toString()`:獲取異常的型別和異常描述資訊(不用)。 **出現異常,最簡單的方式就是把異常的簡單類名,拷貝到API中去查。** ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2019101716021431.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) ## 1.3 異常分類 我們平常說的異常就是指`Exception`,因為這類異常一旦出現,我們就要對程式碼進行更正,修復程式。 **異常(Exception)的分類**:根據在編譯時期還是執行時期去檢查異常? * **編譯時期異常**:checked異常。在編譯時期,就會檢查,如果沒有處理異常,則編譯失敗。(如日期格式化異常) * **執行時期異常**:runtime異常。在執行時期,檢查異常.在編譯時期,執行異常不會編譯器檢測(不報錯)。(如數學異常) ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191006153720391.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) ![​ \[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-yWbBNQxN-1570323592247)(img\異常的分類.png)\]](https://img-blog.csdnimg.cn/20191006090354107.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) ## 1.4 異常的產生過程解析 先執行下面的程式,程式會產生一個數組索引越界異常`ArrayIndexOfBoundsException`。我們通過圖解來解析下異常產生的過程。 工具類 ~~~java public class ArrayTools { // 對給定的陣列通過給定的角標獲取元素。 public static int getElement(int[] arr, int index) { int element = arr[index]; return element; } } ~~~ 測試類 ~~~java public class ExceptionDemo { public static void main(String[] args) { int[] arr = { 34, 12, 67 }; intnum = ArrayTools.getElement(arr, 4) System.out.println("num=" + num); System.out.println("over"); } } ~~~ 上述程式執行過程圖解: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191006090436252.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) # 2、 異常的處理 Java異常處理的五個關鍵字:`try`、`catch`、`finally`、`throw`、`throws` ## 2.1 丟擲異常throw 在編寫程式時,作為一個優秀的程式設計師必須要考慮程式出現問題的情況。舉個栗子,在定義方法時,方法需要接受引數。那麼,當呼叫方法使用接受到的引數時,首先需要先對引數資料進行合法的判斷,資料若不合法,就應該告訴呼叫者,傳遞合法的資料進來。這時需要使用丟擲異常的方式來告訴呼叫者。這個時候throw就派上用場了! > 在java中,提供了一個**throw**關鍵字,Throw用來丟擲一個指定的異常物件。從而可以 > > 1、建立一個異常物件。封裝一些提示資訊(資訊可以自己編寫)。 > > 2、通過關鍵字`throw`就可以將這個異常物件告知給呼叫者,還可以將這個異常物件傳遞到呼叫者處。 > #### throw小結 `throw`**用在方法內**,後面接一個**異常物件**,使用格式為`throw new 異常類名(引數);`,將這個異常物件傳遞到呼叫者處,並結束當前方法的執行。 **throw使用的格式如下**: ~~~java throw new NullPointerException("要訪問的arr陣列不存在"); throw new ArrayIndexOutOfBoundsException("該索引在陣列中不存在,已超出範圍"); ~~~ **使用throw的例項使用**: ~~~java public class ThrowDemo { public static void main(String[] args) { //建立一個數組 int[] arr = {2,4,52,2}; //根據索引找對應的元素 int index = 4; int element = getElement(arr, index); System.out.println(element); System.out.println("over"); } /* * 根據 索引找到陣列中對應的元素 */ public static int getElement(int[] arr,int index){ //判斷 索引是否越界 if(index<0 || index>arr.length-1){ /* 判斷條件如果滿足,當執行完throw丟擲異常物件後,方法已經無法繼續運算。 這時就會結束當前方法的執行,並將異常告知給呼叫者。這時就需要通過異常來解決。 */ throw new ArrayIndexOutOfBoundsException("哥們,角標越界了~~~"); } int element = arr[index]; return element; } } ~~~ `throw`執行效果分析: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191006105950311.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) **再來看看不使用throw的例項使用的執行**: ```javascript public static void main(String[] args) { //建立一個數組 int[] arr = {2,4,52,2}; //根據索引找對應的元素 int index = 4; //注意索引4已經越界了 int ele=arr[index]; System.out.println(ele); System.out.println("over"); } ``` 執行結果 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20191006110517797.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) 這樣一對比`throw`的優勢就不言而喻了~ ## 2.2 Objects非空判斷 還記得`Objects`類嗎,曾經提到過它由一些靜態的實用方法組成,這些方法是`null-save`(空指標安全的)或`null-tolerant`(容忍空指標的),那麼在它的原始碼中,對物件為null的值進行了丟擲異常操作。 `public