一:異常的概念:
Java把異常當作對象來處理,并定義一個基類java.lang.Throwable作為所有異常的超類。
在Java API中已經定義了許多異常類,這些異常類分為兩大類,錯誤Error和異常Exception。
我們先檢視一下異常類的樹狀體系結構,如下:

Thorwable類所有異常和錯誤的超類,有兩個子類Error和Exception,分别表示錯誤和異常。其中異常類Exception又分為運作時異常(RuntimeException)和非運作時異常, 這兩種異常有很大的差別,也稱之為不檢查異常(Unchecked Exception) 和檢查異常(Checked Exception)。
1:Error和Exception
Error是程式無法處理的錯誤,比如OutOfMemoryError、ThreadDeath等。這些異常發生時, Java虛拟機(JVM)一般會選擇線程終止。
Exception是程式本身可以處理的異常,這種異常分兩大類運作時異常(不可查異常)和非運作時異常(可查異常)。 程式中應當盡可能去處理這些異常。
2:運作時異常和非運作時異常
運作時異常都是RuntimeException類及其子類異常,如NullPointerException、IndexOutOfBoundsException等, 這些異常是不檢查異常,程式中可以選擇捕獲處理,也可以不處理。這些異常一般是由程式邏輯錯誤引起的, 程式應該從邏輯角度盡可能避免這類異常的發生。
這類異常程式不要求必須去做處理。
非運作時異常是RuntimeException以外的異常,類型上都屬于Exception類及其子類。 從程式文法角度講是必須進行處理的異常,如果不處理,程式就不能編譯通過。 如IOException、SQLException等以及使用者自定義的Exception異常,一般情況下不自定義檢查異常。
這類異常則要求我們對這個異常進行處理,要麼使用try--catch--finally,要麼使用throws去聲明這個異常。
二:異常的處理:
首先在java中,都是通過 try--catch--finally,throw,throws關鍵字進行的。
1:異常處理的基本文法:
try--catch--finally:
1 package Enum;
2
3 public class MyClass{
4 public static void main(String[] args) {
5 try {
6 //可能會出現異常的代碼塊
7 } catch (Exception e) {//想要捕獲的異常
8 //異常的處理
9 e.printStackTrace();
10 }finally{
11 //不管怎樣都會被運作的語句,例如關閉連結資源,關閉連接配接對象
12 }
13 }
14 }
1: try語句塊,表示要嘗試運作代碼,try語句塊中代碼受異常監控,其中代碼發生異常時,會抛出異常對象。
catch語句塊會捕獲try代碼塊中發生的異常并在其代碼塊中做異常處理,catch語句帶一個Throwable類型的參數, 表示可捕獲異常類型。當try中出現異常時,catch會捕獲到發生的異常,并和自己的異常類型比對, 若比對,則執行catch塊中代碼,并将catch塊參數指向所抛的異常對象。catch語句可以有多個, 用來比對多個中的一個異常,一旦比對上後,就不再嘗試比對别的catch塊了,是以如果需要比對多個異常就把異常的子類放到前面,父類放到後面。 通過異常對象可以擷取異常發生時完整的JVM堆棧資訊,以及異常資訊和異常發生的原因等。
finally語句塊是緊跟catch語句後的語句塊,這個語句塊總是會在方法傳回前執行, 而不管是否try語句塊是否發生異常。并且這個語句塊總是在方法傳回前執行。 目的是給程式一個補救的機會。這樣做也展現了Java語言的健壯性。
2、 try、catch、finally三個語句塊應注意的問題 :
第一、try、catch、finally三個語句塊均不能單獨使用,三者可以組成 try...catch...finally、try...catch、
try...finally三種結構,catch語句可以有一個或多個,finally語句最多一個。
第二、try、catch、finally三個代碼塊中變量的作用域為代碼塊内部,分别獨立而不能互相通路。
如果要在三個塊中都可以通路,則需要将變量定義到這些塊的外面。
第三、多個catch塊時候,隻會比對其中一個異常類并執行catch塊代碼,而不會再執行别的catch塊,
并且比對catch語句的順序是由上到下。
throw、throws關鍵字
throw關鍵字是用于方法體内部,用來抛出一個Throwable類型的異常。如果抛出了檢查異常, 則還應該在方法頭部聲明方法可能抛出的異常類型。該方法的調用者也必須檢查處理抛出的異常。 如果所有方法都層層上抛擷取的異常,最終JVM會進行處理,處理也很簡單,就是列印異常消息和堆棧資訊。 如果抛出的是Error或RuntimeException,則該方法的調用者可選擇處理該異常。有關異常的轉譯會在下面說明。
throws關鍵字用于方法體外部的方法聲明部分,用來聲明方法可能會抛出某些異常。僅當抛出了檢查異常, 該方法的調用者才必須處理或者重新抛出該異常。當方法的調用者無力處理該異常的時候,應該繼續抛出。
例如throws申明一個異常:
1 public void test() throws ClassNotFoundException{
3 }
例如這個throw 觀察一下有什麼不同:
1 public void test() throws ClassNotFoundException {
2 throw new ClassNotFoundException();
3
4 }
5
6
7
8
9
10 public void test() {
11 throw new RuntimeException();
12
13 }
這很好的說明了 throw對與可查異常和不可查異常處理之間的差别
Throwable類中的常用方法
getCause():傳回抛出異常的原因。如果 cause 不存在或未知,則傳回 null。
getMessage():傳回異常的消息資訊。
printStackTrace():對象的堆棧跟蹤輸出至錯誤輸出流,作為字段 System.err 的值。
1 public class MyClass{
2 public static void main(String[] args) {
3
4 try {
5
6 } catch (Exception e) {
7 // TODO: handle exception
8 e.printStackTrace();
9 e.getMessage();
10 e.getCause();
11
12 }
13 }
14
三:異常的一般原則:
1、 能處理就早處理,抛出不去還不能處理的就想法消化掉或者轉換為RuntimeException處理。
因為對于一個應用系統來說,抛出大量異常是有問題的,應該從程式開發角度盡可能的控制異常發生的可能。
2、 對于檢查異常,如果不能行之有效的處理,還不如轉換為RuntimeException抛出。
這樣也讓上層的代碼有選擇的餘地――可處理也可不處理。
3、 對于一個應用系統來說,應該有自己的一套異常處理架構,這樣當異常發生時,也能得到統一的處理風格,
将優雅的異常資訊回報給使用者。
四:自定義異常:
首先 建立一個類繼承異常類,代碼如下:
1 package Exection;
2
3 public class Myexecption extends Exception{
4
5 public Myexecption() {
6 super();
7 // TODO Auto-generated constructor stub
8 }
9
10 public Myexecption(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
11 super(message, cause, enableSuppression, writableStackTrace);
12 // TODO Auto-generated constructor stub
13 }
14
15 public Myexecption(String message, Throwable cause) {
16 super(message, cause);
17 // TODO Auto-generated constructor stub
18 }
19
20 public Myexecption(String message) {
21 super(message);
22 // TODO Auto-generated constructor stub
23 }
24
25 public Myexecption(Throwable cause) {
26 super(cause);
27 // TODO Auto-generated constructor stub
28 }
29
30 }
然後編寫代碼 ,然後編寫邏輯,這個異常什麼時候需要使用,
1 package Exection;
2
3 public class Test {
4 public static int shang (int x,int y) throws Myexecption{
5 if(y==0)
6 {
7 throw new Myexecption("您輸入的是"+y+",規定除數不能為0!");//抛出異常
8 }
9 return x/y;
10 }
11
12 public static void main(String[] args) throws Myexecption {
13 shang(10, 0);
14 }
15 }
在需要的地方抛出這個異常。
運作結果如下:
好了 異常就到這了;
歡迎大家一起說出自己的想法。