Java核心技術卷一 第11章 異常、斷言和日誌

  處理錯誤                                      日誌

  捕獲異常                                      調試技巧

  使用異常機制的技巧                GUI程序排錯技巧

  使用斷言                                      使用調試器

         如果一個用戶在運行程序期間,由於程序的錯誤或一些外部環境的影響造成用戶數據的丟失,用戶就有可能不再使用這個程序了。爲了避免這類事情的發生,至少應該做到以下幾點:

  • 向用戶通告錯誤;
  • 保存所有的工作結果;
  • 允許用戶已妥善的形式退出程序。

         對於異常情況,Java使用一種稱爲異常處理(exception handing)的錯誤捕獲機制處理。

11.1  處理錯誤

    如果由於出現錯誤而使得某些錯做沒有完成,程序應該:

  • 返回到一種安全狀態,並能夠讓用戶執行一些其他的命令。
  • 允許用戶保存所有操作的結果,並以一種適當的方式終止程序。

 

11.1.1  異常分類

    Java程序設計語言中,異常對象都是派生於Throwable類的一個實例。


1  Java中的異常層次結構

    所有的異常都是由Throwable繼承而來,但在下一層立即分解爲兩個分支:Error

Exception

    Error類層次結構描述了Java運行時系統內部錯誤和資源耗盡錯誤。

    Exception層次結構劃分爲兩個分支:由程序錯誤導致的異常屬於RuntimeException;而程序本身沒有問題,但由於像I/O錯誤這類問題導致的異常屬於其他異常。

    Java語言規範將派生於Error類或RuntimeException類的所有異常稱爲未檢查(unchecked)異常,將所有其他的異常稱爲已檢查(checked)異常。

 

11.1.2  聲明已檢查異常

    如果遇到無法處理的情況,那麼Java的方法可以拋出一個異常。

    方法應該在其首部聲明所有可能拋出的異常。

    遇到下面4中情況應該拋出異常:

  • 調用一個拋出已檢查異常的方法。
  • 程序運行過程中發現錯誤,並利用throw語句拋出一個已檢查異常。
  • 程序錯誤,例如啊a[-1]=0會拋出一個ArrayIndexOutOfBoundsException這樣的未檢查異常。
  • Java虛擬機和運行時庫出現內部錯誤。

    對於那些可能被他人使用的Java方法,應該根據異常規範,在方法的首部聲明這個方法可能拋出的異常。

 

11.1.3  如何拋出異常

    對一個已存在的異常類,將其拋出方法:

    1)找到一個合適的異常類。

         2)創建這個類的一個對象。

         3)將對象拋出。

 

11.1.4  創建異常類

    定義一個派生於Exception的類,或者派生於EXception子類的類。

    定義的類應該包含兩個構造器,一個是默認構造器;另一個是帶有詳細描述信息的構造器。

 

11.2  捕獲異常 

    想要捕獲異常,必須設置try/catch語句塊。

    如果在try語句塊中的任何代碼拋出了一個在catch子句中說明的異常類,那麼

1)程序將跳過try語句塊的其餘代碼。

2)程序將執行catch子句中的處理器代碼。

    如果在try語句塊中的代碼沒有拋出任何異常,那麼程序將跳過catch子句。

    如果方法中的任何代碼拋出了一個在catch子句中沒有聲明的異常類型,那麼這個方法就會立刻退出。

    通常,應該捕獲那些知道如何處理的異常,而將那些不知道怎樣處理的異常繼續進行傳遞。

 

11.2.1  捕獲多個異常

    在一個try語句塊中可以捕獲多個異常類型,並對不同類型的異常做出不同的處理。可以按照下列方式爲每個異常類型使用一個單獨的catch子句:


    異常對象可能包含與異常本身有關的信息。想要獲得對象的更多信息,可以試着使用e.getMessage()得到詳細的錯誤信息,或者使用e.getClass().getName()的到異常對象的實際類型。

    Java SE 7 中,同一個catch子句可以捕獲多個異常類型。如果對應異常的動作是一樣的,就可以合併catch子句:


    只有當捕獲的異常類型彼此之間不存在子類關係時才需要這個特性。

 

11.2.2  再次拋出異常與異常鏈

    catch子句中可以拋出一個異常,這樣可以讓用戶拋出子系統中的高級異常,而不會丟失原始異常的細節。

    沒弄明白是什麼意思,只知道可以記錄一個異常,然後再把它重新拋出,而不做任何改變。


 

11.2.3  finally子句

    不管異常是否被捕獲,finally子句中的代碼都被執行。

1)代碼沒有拋出異常。程序首先執行try語句塊中的全部代碼,然後執行finally子句中的代碼。隨後執行try語句塊之後的第一條語句。

2)拋出一個在catch子句中捕獲的異常。程序首先執行try語句塊中的所有代碼,直到發生異常爲止。此時,將跳過try語句塊中的剩餘代碼,轉去執行與該異常匹配的catch子句中的代碼,最後執行finally子句中的代碼。

3)代碼拋出了一個異常,但這個異常不是由catch子句捕獲的。程序首先執行try語句塊中的所有代碼,直到異常被拋出爲止。此時,將跳過try語句塊中的剩餘代碼,轉去執行finally子句中的語句,並將異常拋給這個方法的調用者。

    try語句可以只有finally子句,而沒有catch子句。

 

11.2.4  帶資源的try語句


    假如資源屬於一個實現了AutoCloseable接口的類,Java SE 7 爲這種代碼模式提供了一個很有用的快捷方式,AutoCloseable接口有一個方法:

void close() throws Exception

    try語句塊退出時,會自動調用res.close()

 

11.2.5  分析堆棧跟蹤元素

    堆棧跟蹤是一個方法調用過程的列表,它包含了程序執行過程中方法調用的特定位置。

    可以調用Throwable類的printStackTrace方法訪問堆棧跟蹤的文本描述信息。

11.3  使用異常機制的技巧

  • 異常處理不能代替簡單的測試,只在異常情況下使用異常機制。
  • 不要過分地細化異常
  • 利用異常層次結構
  • 不要壓抑異常
  • 在檢查錯誤時,苛刻要比放任更好
  • 不要羞於傳遞異常

11.4  使用斷言

    斷言機制允許在測試期間向代碼中插入一些檢查語句,當代碼發佈時,這些插入的檢測語句將會被移走。

    斷言格式:

  • assert 條件;
  • assert 條件:表達式;

    這兩種形式都會對條件進行檢測,如果結果爲false,則拋出一個AssertionError異常。第二種形式中,表達式將被傳入AssertionError的構造器,並轉行成一個消息字符串。



 

11.4.1  啓用和禁用斷言

    在默認情況下,斷言被禁用。

    可以在運行程序時使用-enableassertions-ea選項啓用它:java-enableassertions MyApp

    啓用或禁用斷言時不必重新編譯程序。

    開發工具中啓用斷言:

1.在eclipse中,Run-> Run Configurations -> Arguments頁籤 -> VMarguments文本框中加上斷言開啓的標誌:-enableassertions 或者-ea

2.在myEclipse中,Windows-> Preferences ->Java ->Installed JREs ->點擊正使用的JDK ->Edit->Default VM Arguments文本框中輸入:-ea

 

11.4.2  使用斷言完成參數檢查

    選擇斷言的條件:

  • 斷言失敗是致命的、不可恢復的錯誤。
  • 斷言檢查只用於開發和測試階段。

    不應該使用斷言向程序的其他部分通告發生了可恢復的錯誤,或者,不應該作爲程序向用戶通告問題的手段。

    斷言只應該用於在測試階段確定程序內部的錯誤位置。

11.5  記錄日誌

    記錄日誌API就是爲了幫助程序員定位問題而設計的。這些API的優點有:

  • 可以很容易地取消全部日誌記錄,或者僅僅取消某個級別的日誌,而且打開和關閉這個操作也很容易。
  • 可以簡單地禁止日誌記錄和輸出,因此,這些日誌代碼留在程序中的開銷很小。
  • 日誌記錄可以被定向到不同的處理器,用於在控制檯中顯示,用於存儲在文件中等。
  • 日誌記錄器和處理器都可以對記錄進行過濾。過濾器可以根據過濾實現器制定的標準丟棄那些無用的記錄。
  • 日誌記錄可以採用不同的方式可視化,例如村文本或XML
  • 應用程序可以採用多個日誌記錄器,它們使用類似包名的這種具有層次結構的名字。
  • 在默認情況下,日誌系統的配置由配置文件控制。如果需要的話,應用程序可以替換這個配置。

 

Java核心技術介紹的日誌應該是Java自帶的日誌系統,JDBC中好像重新封裝了日誌功能,到時候再來比較。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章