異常、日誌、斷言和除錯
1.處理異常
1.1異常分類
所有異常都由Throwable繼承而來,分為兩個分支:
Error類:Java執行時系統內部錯誤和資源耗盡錯誤。
Exception類:兩個分支:RuntimeException和IOException
RuntimeException:由程式錯誤導致的異常,包含情況:(1)錯誤型別轉換(2)陣列訪問越界(3)訪問空指標;
IOException:程式本身沒有問題,其他異常,包含情況:(1)試圖在檔案尾部後面讀取資料(2)試圖開啟一個錯誤格式的URL(3)試圖根據給定字串查詢Class物件,而這個字串表示的類並不存在
未檢查異常:派生於Error類或RuntimeException類;
已檢查異常:其他異常。
編譯器將檢查是否為所有已檢查異常提供異常處理器。
1.2宣告已檢查異常
方法應該在其首部宣告所有可能丟擲的異常。在下面4種情況應在方法中丟擲異常:
(1)呼叫一個丟擲已檢查異常的方法;
(2)程式執行過程中發現錯誤,並利用throw語句丟擲一個已檢查異常
(3)程式出現錯誤
(4)Java虛擬機器和執行時庫出現的內部異常
如果一個方法有可能丟擲多個已檢查異常,那麼必須在方法首部列出所有異常類,逗號分隔。
!!子類中覆蓋超類的一個方法,則子類方法中宣告的已檢查異常不能超過超類方法中宣告的異常範圍。
1.3丟擲異常
1.4建立自定義異常
1.5捕獲異常
如果異常發生時沒有在任何地方進行捕獲,程式會終止執行。
try{
...
}catch(){
...
}
如果try語句塊中的任何程式碼丟擲了一個在catch字句中說明的異常類,那麼:
(1)程式會跳過try塊中其餘程式碼
(2)執行catch字句中處理器程式碼
未丟擲異常則跳過catch字句。
通常,捕獲知道如何處理的異常,丟擲不知如何處理的異常。
1.6可以捕獲異常後再丟擲異常,目的:改變異常型別
try{
...
}catch(SQLException e){
Throwable se = new ServletException("database error" );
se.initCause(e);
throw se;
}
//捕獲到異常時,重新得到原始異常:Throwable e = se.getCause();
1.7Finally字句
不管是否有異常被捕獲,finally字句中的程式碼都被執行(可以確保關閉資料庫連線)。
InputStream in = ...;
try{
try{
...
}finally{
in.close();
}
}catch(IOException e){
...
}
//這種結構可以報告finally字句中出現的錯誤
1.8分析堆疊跟蹤元素
Throwable t = new Throwable();
StackTraceElement[] frames = t.getStackTrace();
for(StackTraceElement fram:frames){
...
}
Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();
for(Thread t:map.keySet()){
StackTraceElement[] frames = map.get(t);
...
}
2.斷言
斷言機制允許在測試期間向程式碼中插入一些檢查語句。當代碼釋出時,這些插入的檢測語句將會被自動的移走。
3.記錄日誌
3.1基本日誌
預設日誌記錄器:Logger.global
呼叫info方法記錄日誌資訊:Logger.global.info(“File->Open menu item selected”);
記錄內容自動包含時間、呼叫的類名和方法名。
取消所有日誌:Logger.global.setLevel(Level.OFF).
3.2高階日誌
第一次請求一個具有給定名字的日誌記錄器時,就會建立這個記錄器:
Logger myLogger = Logger.getLogger(“com.mycompany.myapp”)
日誌記錄器的父與子間共享某些屬性。如:”com.mycompany.myapp”會繼承”com.mycompany”日誌記錄器的日誌級別。
7個日誌記錄器級別:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST.(預設只記錄前三個級別)
設定級別:logger.setLevel(Level.FINE);此時,FINE和更高級別的記錄都可以記錄下來。
開啟所有級別記錄:Level.ALL;
關閉所有級別記錄:Level.OFF.
所有級別都有記錄方法:logger.warning(message);logger.fine(message).
還可用log方法指定級別:logger.log(Level.FINE,message);
預設日誌記錄將顯示包含日誌呼叫類名和方法名,像堆疊顯示的那樣。
如果虛擬機器對執行過程進行了優化,就得不到準確呼叫資訊。此時可用logp方法:
void logp(Level l,String className,String methodName,String message)
3.3修改日誌管理器配置
3.4本地化
3.5處理器
日誌記錄器預設將記錄傳送到ConsoleHandler中,並由它輸出到System.err流中。
3.6過濾器
3.7格式化器
3.8日誌記錄說明
4.除錯
(1)myeclipse中,Run->Debug As->Java Application啟動偵錯程式。
(2)滑鼠移到希望設定斷點的那一行,在左側空白處右擊,選擇”Toggle Breakpoint”
(3-1)Run->Step Into(快捷鍵”F5”):跟蹤到每個方法呼叫的內部;
(3-2)Run->Step Over(快捷鍵”F6”):定位到下一行。