1.在Java程序設計語言中,異常對象都是派生於Throwable類的一個實例。在Throwable的下一層分解爲兩個分支:Error和Exception。
Error類層次結構描述了Java運行時系統的內部錯誤和資源耗盡錯誤。應用程序不應該拋出這種類型的對象。如果出現了這樣的內部錯誤,除了通告給用戶,並盡力使程序安全地終止之外,再也無能爲力了。這種情況很少出現。
設計Java程序時,需要關注Exception層次結構。這個層次結構又分解爲兩個分支:一個分支派生於RuntimeException;另一個分支包含其他異常。劃分兩個分支的規則是:由程序錯誤導致的異常屬於RuntimeException;而程序本身沒有問題,但由於像I/O錯誤這類問題導致的異常屬於其他異常。
派生於RuntimeException的異常包含以下幾個情況:
(1)錯誤的類型轉換
(2)數組訪問越界
(3)訪問空指針
不是派生於RuntimeException的異常包括:
(1)試圖在文件尾部讀取數據
(2)試圖打開一個錯誤格式的URL
(3)試圖根據給定的字符串查找Class對象,而這個字符串表示的類並不存在
如果出現RuntimeException異常,那麼就一定是程序員的問題。
Java語言規範將派生於Error類或RunTimeException類的所有異常稱爲未檢查(unchecked)異常,所有其他的異常稱爲已檢查(checked)異常。
一個方法必須聲明所有可能拋出的已檢查異常,而未檢查異常要麼不可控制(Error),要麼就應該避免發生(RuntimeException)。如果方法沒有聲明所有可能發生的已檢查異常,編譯器就會給出一個錯誤消息。
2.如果在子類中覆蓋了超類的一個方法,子類方法中聲明的已檢查異常不能超過超類方法中聲明的異常範圍。特別需要說明的是,如果超類方法沒用拋出任何已檢查異常,子類也不能拋出任何已檢查異常。
3.在C++和Java中,拋出異常的過程基本相同,只有一點微小的差別。在Java中只能拋出Throwable子類的對象,而在C++中,卻可以拋出任何類型的值。
4.爲了讓用戶拋出子系統中的高級異常,而不會丟失原始異常的細節,可以使用如下包裝技術:
try
{
XXXXXX
}
catch(Exception e)
{
Throwable mye = new MyException("my info");
mye.initCause(e);
throw mye;
}
當捕獲到異常時,就可以使用下面這條語句重新得到原始異常:
Throwable e = mye.getCause();
5.在JavaSE5.0中,增加了一個靜態的Thread.getAllStackTrace方法,它可以產生所有線程的堆棧跟蹤。方法的具體實現方式如下:
Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();
for(Thread t:map.keySet())
{
StackElement[] frames = map.get(t);
分析 frames
}
6.使用斷言的建議:
斷言失敗是致命的,不可恢復的錯誤
斷言檢查只用於開發和測試階段
因此,不應該使用斷言向程序的其他部分通告發生了可恢復性的錯誤,或者,不應該作爲程序向用戶通告問題的手段。斷言只應該用於在測試階段確定程序內部的錯誤位置。