天天看點

Java異常摘要

1、異常機制

異常機制是指當程式出現錯誤後,程式如何處理。具體來說,異常機制提供了程式退出的安全通道。當出現錯誤後,程式執行的流程發生改變,程式的控制權轉移到異常處理器。

2、異常處理流程

在Java程式的執行過程中,如果出現了異常事件,就會生成一個異常對象。生成的異常對象将傳遞給Java運作時系統,這一異常的産生和送出過程稱為抛棄(throw)異常。當Java運作時系統得到一個異常對象時,它将會尋找處理這一異常的代碼。找到能夠處理這種類型的異常的方法後,運作時系統把目前異常對象交給這個方法進行處理,這一過程稱為捕獲(catch)異常。如果Java運作時系統找不到可以捕獲異的方法,則運作時系統将終止,相應的Java程式也将退出。

3、異常分類

3.1 執行異常

執行異常即運作時異常,繼承于RuntimeException。Java編譯器允許程式不對它們做出處理。下面列出了主要的運作時異常:

ArithmeticException:一個不尋常算術運算産生的異常。

ArrayStoreException:存入數組的内容資料類型不一緻所産生的異常。

ArrayIndexOutOfBoundsException:數組索引超出範圍所産生的異常。

ClassCastExcption:類對象強迫轉換造成不當類對象所産生的異常。

IllegaArgumentException:程式調用時,傳回錯誤自變量的資料類型。

IllegaThreadStateException:線程在不合理狀态下運作所産生的異常。

NumberFormatException:字元串轉換數值所産生的異常。

IllegaMonitorStateException:線程等候或通知對象時所産生的異常。

IndexOutOfBoundsException:索引超出範圍所産生的異常。

NegativeException:數組建立負值索引所産生的異常。

NullPointerException:對象引用參考值為null所産生的異常。

SecurityException:違反安全所産生的異常。

3.2 檢查異常

除了執行異常外,其餘的子類是屬于檢查異常類也稱為非運作時異常,它們都在java.lang類庫内定義。Java編譯器要求程式必須捕獲或者聲明抛棄這種異常。下面列出了主要的檢查異常:

ClassNotFoundException:找不到類或接口所産生的異常。

CloneNotSupportedException:使用對象的clone方法但無法執行Cloneable所産生的異常。

IllegaAccessException:類定義不明确所産生的異常。

InstantiationException:使用newInstance方法試圖建立一個類instance時所産生的異常。

InterruptedException:目前線程等待執行,另一線程中斷目前線程所産生的異常。

3.3 錯誤異常

Error類與異常一樣,它們都是繼承自java.lang.Throwable類。Error 類對象由 Java 虛拟機生成并抛出。Error類包括linkageError(結合錯誤)與VitualmachineError(虛拟機錯誤)兩種子類。

打開JDK的ThreadDeath類的文檔,可以看到下面這段說明:“特别地,雖然出現ThreadDeath是一種‘正常的情形’,但ThreadDeath類是Error而不是Exception的子類,因為許多應用會捕獲所有的Exception然後丢棄它不再理睬。”這段話的意思是,雖然ThreadDeath代表的是一種普通的問題,但鑒于許多應用會試圖捕獲所有異常然後不予以适當的處理,是以JDK把ThreadDeath定義成了Error的子類,因為Error類代表的是一般的應用不應該去捕獲的嚴重問題。

3.3.1 linkageError

LinkageError 的子類表示一個類依賴于另一個類,但是,在前一個類編譯之後,後一個類的改變會與它不相容。

linkageError包括ClassFormarError,ClassCircularityError,ExceptionIn- InitializerError,NoClassDeFormatError,VeritfyError,UnsatisfidLinkError和IncompatibleClassChangeError等子類。其中IncompatibleClassChangeError類又包含AbtractMethodError,NoSuchFieldError,NoSchMethodError,IllegalAccessError,InstantionError。這些類所代表的意義是:

ClassFormarErro:類格式所産生的錯誤。

ClassCircularityError:無限循所産生的錯誤。

ExceptionInInitializerError:初始化所産生的錯誤。

NoClassDeFormatError:沒有類定義所産生的錯誤。

VeritfyError:類檔案某些資料不一緻或安全問題所産生的錯誤。

UnsatisfidLinkError:Java虛拟機無法找到合适的原始語言(native-language)定義的方法所産生的錯誤。

IncompatibleClassChangeError:不相容類所産生的錯誤。

AbtractMethodError:調用抽象方法所産生的錯誤。

NoSuchFieldError:存取或改變資料域所産生的錯誤。

NoSchMethodError :調用類方法所産生的錯誤。

IllegalAccessError:不合法存取或改變資料域或調用方法所産生的錯誤。

InstantionError:使用抽象類或接口所産生的錯誤。

3.3.2 VitualmachineError

當Java虛拟機崩潰了或用盡了它繼續操作所需的資源時,抛出該錯誤。

VitualmachineError包含InternalError,OutOfMemoryError ,StackOverflow- Error,UnknownError。這些類所代表的意義:

InternalError:虛拟機内部所産生的錯誤。

OutOfMemoryError:虛拟機記憶體不足所産生的錯誤。

StackOverflowError:堆棧無法容納所産生的錯誤。

UnknownError:虛拟機不知名異常所産生的錯誤。

4、異常之間的差別與聯系

4.1 Error與Exception

Error是程式無法處理的錯誤,比如OutOfMemoryError、ThreadDeath等。這些異常發生時,Java虛拟機(JVM)一般會選擇線程終止。

Exception是程式本身可以處理的異常,這種異常分兩大類運作時異常和非運作時異常。程式中應當盡可能去處理這些異常。

4.2 運作時異常和非運作時異常

運作時異常都是RuntimeException類及其子類異常,如NullPointerException、IndexOutOfBoundsException等,這些異常是不檢查異常,程式中可以選擇捕獲處理,也可以不處理。這些異常一般是由程式邏輯錯誤引起的,程式應該從邏輯角度盡可能避免這類異常的發生。

非運作時異常是RuntimeException以外的異常,類型上都屬于Exception類及其子類。從程式文法角度講是必須進行處理的異常,如果不處理,程式就不能編譯通過。如IOException、SQLException等以及使用者自定義的Exception異常,一般情況下不自定義檢查異常。

5、Java異常處理總結

5.1 既然捕獲了異常,就要對它進行适當的處理。不要捕獲異常之後又把它丢棄,不予理睬。改正主要有四個選擇:

1、處理異常。針對該異常采取一些行動,例如修正問題、提醒某個人或進行其他一些處理,要根據具體的情形确定應該采取的動作。再次說明,調用printStackTrace算不上已經“處理好了異常”。 

2、重新抛出異常。處理異常的代碼在分析異常之後,認為自己不能處理它,重新抛出異常也不失為一種選擇。 

3、把該異常轉換成另一種異常。大多數情況下,這是指把一個低級的異常轉換成應用級的異常(其含義更容易被使用者了解的異常)。 

4、不要捕獲異常。

5.2 在catch語句中盡可能指定具體的異常類型,必要時使用多個catch。不要試圖處理所有可能出現的異常。

5.3 保證所有資源都被正确釋放。充分運用finally關鍵詞。

5.4 在異常處理子產品中提供适量的錯誤原因資訊,組織錯誤資訊使其易于了解和閱讀。

是以,在出現異常時,最好能夠提供一些文字資訊。例如目前正在執行的類、方法和其他狀态資訊,包括以一種更适合閱讀的方式整理群組織printStackTrace提供的資訊。

5.5 盡量減小try塊的體積。

5.6 全面考慮可能出現的異常以及這些異常對執行流程的影響。

較為理想的處置辦法是向輸出裝置寫一些資訊,聲明資料的不完整性;另一種可能有效的辦法是,先緩沖要輸出的資料,準備好全部資料之後再一次性輸出。