可直接看這篇文章即可:http://www.importnew.com/26613.html
java異常類圖

非檢查異常(unckecked exception):Error 和 RuntimeException 以及他們的子類。javac在編譯時,不會提示和發現這樣的異常,不要求在程式處理這些異常。是以如果願意,我們可以編寫代碼處理(使用try…catch…finally)這樣的異常,也可以不處理。對于這些異常,我們應該修正代碼,而不是去通過異常處理器處理 。這樣的異常發生的原因多半是代碼寫的有問題。如除0錯誤ArithmeticException,錯誤的強制類型轉換錯誤ClassCastException,數組索引越界ArrayIndexOutOfBoundsException,使用了空對象NullPointerException等等。
檢查異常(checked exception):除了Error 和 RuntimeException的其它異常。javac強制要求程式員為這樣的異常做預備處理工作(使用try…catch…finally或者throws)。在方法中要麼用try-catch語句捕獲它并處理,要麼用throws子句聲明抛出它,否則編譯不會通過。這樣的異常一般是由程式的運作環境導緻的。因為程式可能被運作在各種未知的環境下,而程式員無法幹預使用者如何使用他編寫的程式,于是程式員就應該為這樣的異常時刻準備着。如SQLException , IOException,ClassNotFoundException 等。
更直白的說法:
What:什麼是檢查異常(checked exception)?
就是編譯器要求你必須處置的異常。不知道你程式設計的時候有沒有遇到過,你寫的某段代碼,編譯器要求你必須要對這段代碼try...catch,或者throws exception,如果你遇見過,沒錯,這就是檢查異常,也就是說,你代碼還沒運作呢,編譯器就會檢查你的代碼,會不會出現異常,要求你對可能出現的異常必須做出相應的處理。
What:什麼是非檢查異常(unchecked exceptions)?
編譯器不要求強制處置的異常,雖然你有可能出現錯誤,但是我不會在編譯的時候檢查,沒必要,也不可能。
Why:為什麼有非檢查異常?
你想想非檢查異常都有哪些?NullPointerException,IndexOutOfBoundsException,VirtualMachineError等,這些異常你編譯的時候檢查嗎?再說了,明明可以運作時檢查,都在編譯的時候檢查,你寫的代碼還能看嗎?而且有些異常隻能在運作時才能檢查出來,比如空指針,堆溢出等。
Exception異常進行劃分,它可分為運作時異常和非運作時異常。
What:什麼是運作時異常?
都是RuntimeException類及其子類異常,如NullPointerException(空指針異常)、IndexOutOfBoundsException(下标越界異常)等,這些異常是非檢查異常,程式中可以選擇捕獲處理,也可以不處理。這些異常一般是由程式邏輯錯誤引起的,程式應該從邏輯角度盡可能避免這類異常的發生。
運作時異常的特點是Java編譯器不會檢查它,也就是說,當程式中可能出現這類異常,即使沒有用try-catch語句捕獲它,也沒有用throws子句聲明抛出它,也會編譯通過。
當出現RuntimeException的時候,我們可以不處理。當出現這樣的異常時,總是由虛拟機接管。比如:我們從來沒有人去處理過NullPointerException異常,它就是運作時異常,并且這種異常還是最常見的異常之一。
出現運作時異常後,如果沒有捕獲處理這個異常(即沒有catch),系統會把異常一直往上層抛,一直到最上層,如果是多線程就由Thread.run()抛出,如果是單線程就被main()抛出。抛出之後,如果是線程,這個線程也就退出了。如果是主程式抛出的異常,那麼這整個程式也就退出了。運作時異常是Exception的子類,也有一般異常的特點,是可以被catch塊處理的。隻不過往往我們不對他處理罷了。也就是說,你如果不對運作時異常進行處理,那麼出現運作時異常之後,要麼是線程中止,要麼是主程式終止。
如果不想終止,則必須捕獲所有的運作時異常,決不讓這個處理線程退出。隊列裡面出現異常資料了,正常的處理應該是把異常資料舍棄,然後記錄日志。不應該由于異常資料而影響下面對正常資料的處理。
What:什麼是非運作時異常?
是RuntimeException以外的異常,類型上都屬于Exception類及其子類。從程式文法角度講是必須進行處理的異常,如果不處理,程式就不能編譯通過。如IOException、SQLException等以及使用者自定義的Exception異常,對于這種異常,JAVA編譯器強制要求我們必需對出現的這些異常進行catch并處理,否則程式就不能編譯通過。是以,面對這種異常不管我們是否願意,隻能自己去寫一大堆catch塊去處理可能的異常。
抛出異常有三種形式,一是throw,一個throws,還有一種系統自動抛異常。下面它們之間的異同。
一、系統自動抛異常
當程式語句出現一些邏輯錯誤、主義錯誤或類型轉換錯誤時,系統會自動抛出異常:
public static void main(String[] args) {
int a = 5, b =0;
System.out.println(5/b);
//function();
}
系統會自動抛出ArithmeticException異常
或者
public static void main(String[] args) {
String s = "abc";
System.out.println(Double.parseDouble(s));
//function();
}
系統會自動抛出NumberFormatException異常。
二、throw
throw是語句抛出一個異常,一般是在代碼塊的内部,當程式出現某種邏輯錯誤時由程式員主動抛出某種特定類型的異常
public static void main(String[] args) {
String s = "abc";
if(s.equals("abc")) {
throw new NumberFormatException();
} else {
System.out.println(s);
}
//function();
}
運作時,系統會抛出異常:Exception in thread "main" java.lang.NumberFormatException at......
三、throws
throws是方法可能抛出異常的聲明。(用在聲明方法時,表示該方法可能要抛出異常)
public void function() throws Exception{......}
當某個方法可能會抛出某種異常時用于throws 聲明可能抛出的異常,然後交給上層調用它的方法程式處理
public class testThrows {
public static void function() throws NumberFormatException {
String s = "abc";
System.out.println(Double.parseDouble(s));
}
public static void main(String[] args) {
try {
function();
} catch (NumberFormatException e) {
System.err.println("非資料類型不能強制類型轉換。");
//e.printStackTrace();
}
}
}
運作結果:非資料類型不能強制類型轉換。
四、throw與throws的比較
1: throws出現在方法函數頭;而throw出現在函數體。
2: throws表示出現異常的一種可能性,并不一定會發生這些異常;throw則是抛出了異常,執行throw則一定抛出了某種異常對象。
3: 兩者都是消極處理異常的方式(這裡的消極并不是說這種方式不好),隻是抛出或者可能抛出異常,但是不會由函數去處理異常,真正的處理異常由函數的上層調用處理。
五、程式設計習慣
1: 在寫程式時,對可能會出現異常的部分通常要用try{...}catch{...}去捕捉它并對它進行處理;
2: 用try{...}catch{...}捕捉了異常之後一定要對在catch{...}中對其進行處理,那怕是最簡單的一句輸出語句,或棧輸入e.printStackTrace();
3: 如果是捕捉IO輸入輸出流中的異常,一定要在try{...}catch{...}後加finally{...}把輸入輸出流關閉;
4: 如果在函數體内用throw抛出了某種異常,最好要在函數名中加throws抛異常聲明,然後交給調用它的上層函數進行處理。