小結一下:
* Runtime exceptions:
在定義方法時不需要聲明會拋出runtime exception;
在調用這個方法時不需要捕獲這個runtime exception;
runtime exception是從java.lang.RuntimeException或java.lang.Error類衍生出來的。
* Checked exceptions:
定義方法時必須聲明所有可能會拋出的checked exception;
在調用這個方法時,必須捕獲它的checked exception,不然就得把它的exception傳遞下去;
checked exception是從java.lang.Exception類衍生出來的。
二、邏輯上
從邏輯的角度來說,checked exceptions和runtime exception是有不同的使用目的的。checked exception用來指示一種調用方能夠直接處理的異常情況。而runtime exception則用來指示一種調用方本身無法處理或恢複的程序錯誤。
checked exception迫使你捕獲它並處理這種異常情況。以java.net.URL類的構建器(constructor)為例,它的每一個構建器都會拋出MalformedURLException。MalformedURLException就是一種checked exception。設想一下,你有一個簡單的程序,用來提示用戶輸入一個URL,然後通過這個URL去下載一個網頁。如果用戶輸入的URL有錯誤,構建器就會拋出一個exception。既然這個exception是checked exception,你的程序就可以捕獲它並正確處理:比如說提示用戶重新輸入。
再看下麵這個例子:
public void method()
{
int [] numbers = { 1, 2, 3 };
int sum = numbers[0] + numbers[3];
}
在運行方法method()時會遇到ArrayIndexOutOfBoundsException(因為數組numbers的成員是從0到2)。對於這個異常,調用方無法處理/糾正。這個方法method()和上麵的method2()一樣,都是runtime exception的情形。上麵我已經提到,runtime exception用來指示一種調用方本身無法處理/恢複的程序錯誤。而程序錯誤通常是無法在運行過程中處理的,必須改正程序代碼。
總而言之,在程序的運行過程中一個checked exception被拋出的時候,隻有能夠適當處理這個異常的調用方才應該用try/catch來捕獲它。而對於runtime exception,則不應當在程序中捕獲它。如果你要捕獲它的話,你就會冒這樣一個風險:程序代碼的錯誤(bug)被掩蓋在運行當中無法被察覺。因為在程序測試過程中,係統打印出來的調用堆棧路徑(StackTrace)往往使你更快找到並修改代碼中的錯誤。有些程序員建議捕獲runtime exception並紀錄在log中,我反對這樣做。這樣做的壞處是你必須通過瀏覽log來找出問題,而用來測試程序的測試係統(比如Unit Test)卻無法直接捕獲問題並報告出來。
在程序中捕獲runtime exception還會帶來更多的問題:要捕獲哪些runtime exception?什麼時候捕獲?runtime exception是不需要聲明的,你怎樣知道有沒有runtime exception要捕獲?你想看到在程序中每一次調用方法時,都使用try/catch程序塊嗎?