【java基礎之異常】死了都要try,不淋漓盡致地catch我不痛快!
阿新 • • 發佈:2019-11-05
@[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