異常的定義:程序運行時,發生的不被期望的事件,它阻止了程序按照程序員的預期正常執行,這就是異常。
Thorwable類(表示可拋出)是所有異常和錯誤的超類(頂層父類),兩個直接子類爲Error和Exception,分別表示錯誤和異常。
Error是程序無法處理的錯誤,它是由JVM產生和拋出的,比如OutOfMemoryError內存溢出、ThreadDeath等。這些異常發生時,Java虛擬機(JVM)一般會選擇終止線程。
Exception是程序本身可以處理的異常,這種異常分兩大類:運行時異常(RuntimeException)和非運行時異常。程序中應當儘可能去處理這些異常。這兩種異常有很大的區別,也稱之爲不檢查異常(Unchecked Exception)和檢查異常(Checked Exception)。
運行時異常都是RuntimeException類及其子類異常,如NullPointerException、IndexOutOfBoundsException等,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯誤引起的,程序應該從邏輯角度儘可能避免這類異常的發生。
非運行時異常是RuntimeException以外的異常,類型上都屬於Exception類及其子類。從程序語法角度講是必須進行處理的異常,如果不處理,程序就不能編譯通過。如IOException、SQLException等以及用戶自定義的Exception異常。
一般情況下不自定義檢查異常。
try、catch、finally三個語句塊應注意的問題
第一:try、catch、finally三個語句塊均不能單獨使用,三者可以組成 try…catch…finally、try…catch、try…finally三種結構,catch語句可以有一個或多個,finally語句最多一個。
第二:try、catch、finally三個代碼塊中變量的作用域爲代碼塊內部,分別獨立而不能相互訪問。如果要在三個塊中都可以訪問,則需要將變量定義到這些塊的外面。
第三:多個catch塊時候,最多隻會匹配其中一個異常類且只會執行該catch塊代碼,而不會再執行其它的catch塊,且匹配catch語句的順序爲從上到下,也可能所有的catch都沒執行。
第四:先catch子類異常再Catch父類異常。
finally
無論try中指定的程序塊是否拋出異常,也無論catch語句的異常類型是否與所拋棄的異常類型一致,finally中的代碼塊一定會執行;
finally爲異常處理提供了一個統一的出口,使得在控制流程轉到程序其他部分以前能夠對程序狀態進行統一的管理;
通常在finnally語句中可以進行資源的清理工作,如關閉打開的文件和刪除臨時文件等。
throw、throws關鍵字
throw關鍵字是用於方法體內部,用來拋出一個Throwable類型的異常。如果拋出了檢查異常,則還應該在方法頭部聲明方法可能拋出的異常類型。該方法的調用者也必須檢查處理拋出的異常。如果所有方法都層層上拋獲取的異常,最終JVM會進行處理,處理也很簡單,就是打印異常消息和堆棧信息。
public static void test() throws Exception
{
throw new Exception(“方法test中的Exception”);
}
throws關鍵字用於方法體外部的方法聲明部分,用來聲明方法可能會拋出某些異常。僅當拋出了檢查異常,該方法的調用者才必須處理或者重新拋出該異常。當方法的調用者無力處理該異常的時候,應該繼續拋出。
假設f方法拋出了A異常,則f方法有兩種方式處理A異常:
throws A // 調用者處理異常,因此此處f方法將異常拋出,交給調用f方法的調用者caller
try{......} catch(){.....} // f方法自己處理A異常
PS: 要拋出的異常必須是Throwable類的子類
throws A表示調用f方法時f方法可能拋出A類異常,建議對A類異常進行捕捉;
throws A不表示f方法一定拋出A類異常,也可能不拋出A類異常;
throws A不表示調用f方法時,必須對A異常進行捕捉,例如A是RuntimeException子類異常,編譯器允許調用者對RuntimeException異常不進行異常處理
PSSSSSSS! —— 強烈建議:
對所有throws出的所有異常進行處理;
如果一個方法已經對A異常進行了處理,則不要再throw A
注意一個方法throws出某個異常但是該方法內部可以不throw出該異常,代碼如下:
class ER extends RuntimeException {
}
class SomeClass{
public void fun() throws ER
{
System.out.println("AAAA");
}
}
public class ExceptionTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
SomeClass A = new SomeClass();
A.fun();
}
}
程序運行結果如下:AAAA。