## **一、什么是錯誤異常**
在程序編譯或運行過程中出現了非人為預期或者人為可預期的錯誤,該錯誤導致后續程序無法繼續編譯或者繼續運行稱之為異常。
>[info] 程序的編譯至運行,可以舉例為:你計劃明日騎車至北京,那么分為以下兩個過程:
> 1. 從有想法到正式出發,我們假設為計劃過程,也可以視為程序的編譯過程,如果在整個計劃中發現明天要下雨,這個可以視為是可預計也有可能不可預計(天氣預報說晴朗,但在出發那一刻電閃雷鳴),但總歸這樣的情況是無法再進行下去的,所以可以稱為編譯錯誤,導致程序后續終止。
> 2. 從出發到目的地,我們可以假設為程序的運行階段。在這個過程中,可能會發生一些突發情況,如:車胎漏氣、爆胎、出交通事故等,但總歸再整個計劃到實施過程中會發生影響計劃或終止計劃的情況,我們將它稱為錯誤或異常。
>
> 所以說錯誤和異常都是在程序編譯或執行過程中發生的預期或沒有預期到的情況,但如果要細致區分,可以以能否繼續執行去劃分,發生錯誤寓意著后續無法繼續執行,發生異常寓意著后續可能還能夠執行,只是執行過程中偏離了我們預期的軌道。在Java中,編譯異常我們不可控制,只可控運行錯誤異常也可以由我們自己去拋出。
~~~java
public class run {
public static void main(String [] args){
// 假設a、b均為用戶輸入
int a = 1;
int b = 0;
try{
int c = a/b;
}catch (Exception e){
throw new RuntimeException("輸入數值不符合計算要求:" + e.getMessage());
}
}
}
================================ 運行結果 ================================
Exception in thread "main" java.lang.RuntimeException: 輸入數值不符合計算要求:/ by zero
at run.main(run.java:10)
~~~
<br/>
## **二、Java里常見的錯誤異常**
1. 編譯錯誤:新手比較多,如語法錯誤、聲明錯誤、使用錯誤;
2. 運行時錯誤:程序在執行時,由于傳入參數不符合預期或計算結果不符合要求;
3. 邏輯錯誤:程序沒有按照原定的邏輯進行運行。
>[info] Java中的`Java.lang`的軟件包中有一個`Java.lang.Throwable`類,這個類是Java中所有錯誤和異常的超類,`Throwable`類有兩個子類,`Error`與`Exception`
* **Error - 錯誤**
* Throwable的子類,其中也包含大量子類
* 出錯后程序無法繼續進行,如內存溢出等
* **Exception - 異常**
* Throwable的子類,其中也包含大量子類
* 程序本身可以處理的異常
* 分為兩大類:
* **可查異常**(編輯器要求必須處理的異常):`RuntimeException`及其子類以外,其他的`Exception`類及其子類,如`IOException`和`ClassNotFoundException`;
* **不可查異常**(編輯器不要求強制處理的異常):包括運行時異常(`RuntimeException`及其子類)和錯誤(`Error`),如`ArrayIndexOutOfBoundsException`
:-: 
## **三、如何在代碼編寫中使用異常**
1. 可預見的異常我們可以使用`try cache`進行預期捕獲,如下:
~~~java
try{
// 可能會發生異常的代碼
}catch (ExceptionNameA e){
// 發生A異常時的處理
}catch (ExceptionNameB e){
// 發生B異常時的處理
}finally{
// 肯定要執行的代碼放這里
}
// 例如上面剛開始的例子 我們在粘下來注釋看看
public class run {
public static void main(String [] args){
// 假設a、b均為用戶輸入
int a = 1;
int b = 0;
try{
int c = a/b; // 被除數不能等于0,這里正常會報ArithmeticException異常
}catch (Exception e){
/**
* 此處我們使用Exception類去接異常,ArithmeticException屬于Exception類,如果知道具體的異常
* 的話(如此處的ArithmeticException),我們可以更換成`ArithmeticException e`去定義e的數
* 據類型,甚至可以使用`Throwable e`,因為ArithmeticException是Exception的子類,而Exception
* 又是Throwable的子類
*/
/**
* 在這我們用了一個拋出異常,當然你也可以不用拋出,但在這的邏輯中如果b為0,那么c的結果肯定是我們不
* 能接受的,所以我們通過拋出異常來 *終止* 程序進行,異常的拋出也有各種如:
* // 這是拋出了運行異常
* throw new RuntimeException("輸入數值不符合計算要求:" + e.getMessage());
* // 這是拋出了計算異常
* throw new ArithmeticException("輸入數值不符合計算要求:" + e.getMessage());
*
* 如果c的結果不影響你的使用,那你可以不拋出異常,繼續讓程序走下去:
* System.out.println("警告:輸入數值不合法");
* //throw new RuntimeException("輸入數值不符合計算要求:" + e.getMessage());
*
*/
throw new RuntimeException("輸入數值不符合計算要求:" + e.getMessage());
}
}
}
~~~
>[info] 在我們寫代碼的過程中,我們可以通過定義異常的方式來對程序進行判斷是否能夠繼續下去
2. `throw`和`throws`的區別
* `throw` 可以讓我們在代碼中的某個地方拋出異常,但如果在類的定義中我們使用了`throws`,則這個異常則是拋給了方法調用的代碼塊:
~~~
public class Compute {
// 此處我們將錯誤拋出給調用代碼
public int compute(int a, int b) throws Exception{
int c = 0;
try{
c = a/b;
return c;
}catch (ArithmeticException e){
// 所以這里的錯誤拋給了調用函數,編輯器需要調用函數使用try-catch去捕獲錯誤
throw new Exception("輸入數值不符合計算要求:" + e.getMessage());
}
}
}
public class run {
public static void main(String [] args){
// 假設a、b均為用戶輸入
int a = 1;
int b = 0;
try {
Compute compute = new Compute();
int result = compute.compute(a,b);
System.out.println("result"+result);
}catch (Exception e){
// 捕獲錯誤
System.out.println(e.getMessage());
}
System.out.println("程序結束");
}
}
================================ 運行結果 ================================
輸入數值不符合計算要求:/ by zero
程序結束
進程已結束,退出代碼0
~~~