異常簡介
定義:Java異常是Java提供的一種識別及響應錯誤的一致性機制。
作用:Java異常機制可以使程式中異常處理程式碼和正常業務程式碼分離,保證程式程式碼更加優雅,並提高程式健壯性。在有效使用異常的情況下,異常能清晰的回答what, where, why這3個問題:異常型別回答了“什麼”被丟擲,異常堆疊跟蹤回答了“在哪“丟擲,異常資訊回答了“為什麼“會丟擲。
異常分類
java.lang.Throwable
|– Error錯誤:JVM內部的嚴重問題。無法恢復。程式人員不用處理。
|–Exception異常:普通的問題。通過合理的處理,程式還可以回到正常執行流程。要求程式設計人員要進行處理。
|–RuntimeException:也叫非受檢異常(unchecked exception).這類異常是程式設計人員的邏輯問題。應該承擔責任。Java編譯器不進行強制要求處理。 也就是說,這類異常再程式中,可以進行處理,也可以不處理。
|–非RuntimeException:也叫受檢異常(checked exception).這類異常是由一些外部的偶然因素所引起的。Java編譯器強制要求處理。也就是說,程式必須進行對這類異常進行處理。
複製程式碼
異常處理機制
- 當程式再執行過程中出現了異常,JVM自動建立一個該型別的異常物件。同時把這個異常物件交給執行時系統。(丟擲異常)
- 執行時系統接受到一個異常物件時,它會再產生異常的程式碼附近查詢相應的處理方式。
- 異常的處理方式有兩種:
- 捕獲並處理:在異常的程式碼附近顯示用try/catch進行處理(不合理),執行時系統捕獲後會查詢相應的catch處理塊,再catch處理塊中對該異常進行處理。
- 檢視發生異常的方法是否有向上宣告異常,有向上宣告,向上級查詢處理語句,如果沒有向上宣告,JVM中斷程式的執行並處理。用throws向外宣告(合理的處理方法)
Java異常機制用到的幾個關鍵字:try、catch、finally、throw、throws。
try -- 用於監聽。將要被監聽的程式碼(可能丟擲異常的程式碼)放在try語句塊之內,當try語句塊內發生異常時,異常就被丟擲。
catch -- 用於捕獲異常。catch用來捕獲try語句塊中發生的異常。
finally -- finally語句塊總是會被執行。它主要用於回收在try塊裡開啟的物力資源(如資料庫連線、網路連線和磁碟檔案)。只有finally塊,執行完成之後,才會回來執行try或者catch塊中的return或者throw語句,如果finally中使用了return或者throw等終止方法的語句,則就不會跳回執行,直接停止。
throw -- 用於丟擲異常。
throws -- 用在方法簽名中,用於宣告該方法可能丟擲的異常。
異常處理方式:
1、顯示用try/catch進行處理
try{
//可能會出現異常的程式碼段;
}catch(異常型別1 變數名){ //處理制定型別的異常
//對該型別異常的處理程式碼段;
}catch(異常型別2 變數名){
}finally{
//無論是否發生異常都要執行的程式碼段;
//經常用來清理資源
}
複製程式碼
2、向上宣告:用throws關鍵字,向外宣告本方法可能會丟擲的異常列表。
...方法名(引數列表) throws 異常型別1,異常型別2
複製程式碼
3、手動丟擲一個異常:當程式邏輯不符合期望時,要中止後面程式碼的執行時。在方法的程式碼段中,可以使用throw關鍵字手動丟擲一個異常。 **注意:**如果手動丟擲的是受檢異常,那麼本方法必須進行處理(應該採用向上宣告這個異常);如果手動丟擲的是非受檢異常,那麼可以進行處理,也可以不處理。
異常繼承結構
基類為***Throwable***,Error和Exception繼承Throwable,RuntimeException和IOException、SQLException等繼承Exception。
檢查異常(checked exception)和未檢查異常(unchecked exception)
Error和RuntimeException及其子類成為未檢查異常
(unchecked),其它異常成為已檢查異常
(checked)。
檢查異常:編譯器要求必須處置的異常。
處理方式: 1、通過throws exception繼續丟擲,消極的方法,一直可以拋到java虛擬機器來處理。 2、用try...catch捕獲。 注意:檢查異常必須處理,捕獲或者丟擲。
非檢查異常:編譯器不要求強制處置的異常。這類異常常常只能在執行時才能檢查出來,比如空指標,堆溢位等。
處理方式: 1、捕獲 2、繼續丟擲 3、不處理
執行時異常和非執行時異常
執行時異常: RuntimeException類及其子類,如NullPointerException(空指標異常)、IndexOutOfBoundsException(下標越界異常)等,這些異常是非檢查異常,程式中可以選擇捕獲處理,也可以不處理。一般由程式邏輯錯誤引起。
處理RuntimeException的原則是:如果出現RuntimeException,那麼一定是程式設計師的錯誤。
執行時異常的特點是Java編譯器不會檢查它,也就是說,當程式中可能出現這類異常,即使沒有用try-catch語句捕獲它,也沒有用throws子句宣告丟擲它,如果有異常產生,則異常將由JVM進行處理,編譯也會通過。
對於RuntimeException的子類最好也使用異常處理機制。雖然RuntimeException的異常可以不使用try...catch進行處理,但是如果一旦發生異常,則肯定會導致程式中斷執行,所以,為了保證程式再出錯後依然可以執行,在開發程式碼時最好使用try...catch的異常處理機制進行處理。
非執行時異常:非RuntimeException類及其子類,如IOException、SQLException等以及使用者自定義的Exception異常等,從程式語法角度講是必須進行處理的異常,如果不處理,程式就不能編譯通過。
RuntimeException和Exception
RuntimeException:執行時異常,在專案執行之後出錯則直接中止執行,異常由JVM虛擬機器處理。
Exception,:非執行時異常,在專案執行之前必須處理掉。一般由程式設計師try catch 掉。
自定義異常類需要繼承Exception或RunExcption。
注意:覆蓋父類某方法的子類方法不能丟擲比父類方法更多的異常,所以,有時設計父類的方法時會宣告丟擲異常,但實際的實現方法的程式碼卻並不丟擲異常,這樣做的目的就是為了方便子類方法覆蓋父類方法時可以丟擲異常。
常見的RuntimeException
RuntimeException是開發中最容易遇到的,下面列舉一下常見的RuntimeException:
1、NullPointerException:空指標異常;
2、NumberFormatException:繼承IllegalArgumentException,字串轉換為數字時出現。比如int i= Integer.parseInt("ab3");
3、ArrayIndexOutOfBoundsException:陣列越界。比如 int[] a=new int[3]; int b=a[3];
4、StringIndexOutOfBoundsException:字串越界。比如 String s="hello"; char c=s.chatAt(6);
5、ClassCastException:型別轉換錯誤。比如 Object obj=new Object(); String s=(String)obj;
6、ArithmeticException:算術錯誤,典型的就是0作為除數的時候。
7、IllegalArgumentException:非法引數,在把字串轉換成數字的時候經常出現的一個異常,我們可以在自己的程式中好好利用這個異常。
參考文章連結: