異常使得我們能將每件事都當做一個事務進行考慮,也可以看作是內建的恢復系統。
異常對象也在堆上創建,有兩個構造器,一個是默認,另一個是接受字符串爲參數以便放入相關信息的構造器: throw new NullPointerException("t = null");
創建完對象後,引用將傳遞給 throw。異常對象中僅有的信息就是異常類型,上一層環境通過獲得這些信息來決定如何處理異常對象。
主流語言都是使用異常處理中的“終止模型”,捕獲到異常馬上中斷執行。恢復模型雖然支持不斷自動嘗試解決問題,但是容易導致代碼耦合問題。
將錯誤寫入 System.out 發送給標準錯誤流比 System.out 好,因爲 System.out 可能會被重定向。e.printStackTrace() 會將錯誤信息輸出至標準錯誤流。
printStackTrace() 方法提供的信息可以通過 getStackTrace() 方法直接訪問,該方法將返回一個由棧軌跡中的元素構成的數組,其中每一個元素代表棧中的一幀。0是棧頂元素,並且是調用序列中的最後一個方法調用;最後一個元素和棧底是第一個被調用的方法。
可以通過
catch(Exception e)
{
throw e;
}
重新拋出異常,將異常交給上一級處理,同一個 try 塊的後續 catch 子句將被忽略,並且異常對象的所有信息都得以保持。重新拋出後,如果想要得到異常的新發生地,可以調用 fillInStackTrace() 方法返回一個 Throwable 對象,其通過將當前調用棧信息填入原來的異常對象而建立。
在 Throwable 子類的構造器當中,都可以接受一個 cause 對象作爲參數,以這個 cause 表示原始異常。只有三種基本類型異常類提供了帶 cause 參數的構造器。Error、Exception 以及 RuntimeException。要將其它類型異常連接起來,使用 initCause() 方法。
當需要將內存之外的的資源恢復到初始狀態時需要使用 finally 子句,而且無論有多少個 return 語句在前面,finally 總是會執行。但是如果在 finally 塊中寫入 return 語句,則會導致異常無法正常拋出。
覆蓋方法時,只能拋出在基類方法的異常說明裏列出的異常。然而該限制對於構造器不起作用,但是派生類構造器的異常說明必須包含基類構造器的異常說明且不能捕獲基類構造器拋出的異常。