1. 程式人生 > >CoreJava讀書筆記--異常、斷言和日誌(二)--斷言和日誌

CoreJava讀書筆記--異常、斷言和日誌(二)--斷言和日誌

使用斷言

在一個具有自我保護能力的程式中,斷言很常用。

(一)斷言的概念

斷言機制允許在測試期間向程式碼中插入一些檢查語句。當代碼釋出時,這些插入的檢測語句將會被自動地移走。Java語言引入了關鍵字assert。assert有兩種形式:

assert 條件;

和

assert 條件 : 表示式;

這兩種形式都會對條件進行檢測,如果結果為false,則丟擲一個AssertionError異常。在第二種形式中,表示式將被傳入AssertionError構造器,並轉換成一個訊息字串。表示式部分的唯一目的是產生一個訊息字串。例如:需要計算

double y = Math.sqrt(x);

我們知道x不能為負數,要想使用斷言,只需要簡單地使用assert語句,進行測試即可:

assert x>=0;

或者將x的實際值傳遞給AssertionError物件,從而可以在後面顯示出來。

assert x>=0 : x;

(二)啟用和禁用斷言

在預設情況下,斷言被禁用。可以在執行程式時用-enableassertions或-ea選項啟用:

java -enableassertions MyApp

需要注意的是,在啟用或禁用斷言時不必重新編譯程式。啟用或禁用斷言是類載入器(class loader)的功能。當斷言被禁用時,類載入器將跳過斷言程式碼,因此,不會降低程式執行的速度。

也可以在某個類或整個包中使用斷言,例如:

java -ea:MyClass //斷言某個類

java -ea:com.mycompany.mylib...MyApp  //斷言某個包


//系統類不是由類載入器載入,所以不能用-ea 和-da,而是使用下面開關啟用斷言
-enablesystemassertions/-esa

也可以使用選項-disableassertions或-da禁用某個特定類和包的斷言:

-da:MyClass MyApp

-disableassertions:MyClass

(三)使用斷言完成引數檢查

在Java語言中,給出了3種處理系統錯誤的機制:

  • 丟擲一個異常
  • 日誌
  • 使用斷言

什麼時候應該選擇使用斷言呢?

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

 注意:①不要在public方法裡面檢查引數是不是為null之類的操作

②不要用assert來檢查方法操作的返回值來判斷方法操作的結果

日誌

我們總是用System.out.println方法呼叫來幫助觀察程式執行的操作過程,但是太過複雜,記錄日誌API就是為了解決這個問題而設計的。下面看看記錄日誌API的優點:

①可以很容易的取消全部日誌記錄,或者僅僅取消某個級別的日誌,而且開啟和關閉這個操作也容易

②可以很簡單的禁止日誌記錄的輸出,因此,將這些日誌程式碼留在程式中的開銷很小

③日誌可以被定向到不同的處理器,例如用於在控制檯顯示,用於儲存在檔案中

④日誌記錄器和處理器都可以對記錄進行過濾,過濾器也可以根據實際制定過濾標準,丟棄那些無用的記錄項

⑤日誌記錄可以採用不同的方式格式化,例如:純文字或XML

⑥應用程式可以使用多個日誌記錄器,它們使用類似包名的這種具有層次結構的名字

⑦在預設情況下,日誌系統的配置由配置檔案控制

(一)基本日誌

要生成簡單的日誌記錄,可以使用全域性日誌記錄器(global logger)並呼叫其info方法:

Logger.getGlobal().info("File->Open menu item selected");

也可以在適當地方呼叫關閉全域性記錄器的方法:

Logger.getGlobal().setLevel(Level.OFF);

將會取消所有的日誌。

(二)高階日誌

在一個專業的應用程式中,不要將所有的日誌都記錄到一個全域性日誌記錄器中,而是可以自定義日誌記錄器。可以呼叫getLogger方法建立或獲取記錄器:

private static final Logger myLogger = Logger.getLogger("com.company.myapp");

提示:未被任何變數引用的日誌記錄器可能會被垃圾回收。為了防止這種情況發生,要像上面的例子中一樣,用一個靜態變數儲存日誌記錄器的一個引用。

與包名類似,日誌記錄器名也具有層次結構。事實上,日誌記錄器也有級別,通常,有以下7個日誌記錄器級別:

  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST

在預設情況下,只記錄前三個級別,也可以設定其他的級別。例如:

logger.setLevel(Level.FINE);

現在,FINE和更高級別的記錄都可以記錄下來。另外,也可以使用Level.ALL開啟所有級別的記錄,或者使用Level.OFF關閉所有級別的記錄。

預設的日誌記錄將顯示包含日誌呼叫的類名和方法名,如同堆疊所顯示的那樣。但是,如果虛擬機器對執行過程進行了優化,就得不到準確的呼叫資訊。此時,可以呼叫logp方法獲得呼叫類和方法的確切位置,這個方法的簽名為:

void logp(Level lev,String className,String methodName,String message)

(三)修改日誌管理器配置

可以通過編輯配置檔案來修改日誌系統的各種屬性。在預設情況下,配置檔案存在於:

jre/lib/logging.properties

要想使用另一個配置檔案,就要將java.util.logging.config.file特性設定為配置檔案的儲存位置,並用下列命令啟動應用程式:

java -Djava.util.logging.config.file=configFile MainClass

要想修改預設的日誌記錄級別,就需要編輯配置檔案,並修改以下命令列

.level = INFO

可以通過新增以下內容來指定自己的日誌記錄級別

com.mycompany.myapp.level=FINE

之後可以看到,我們這麼設定是不能在控制檯上看到日誌記錄的,這是處理器的任務。另外,處理器也有級別。要想在控制檯上看到FINE級別的訊息,就需要進行下列設定:

java.util.logging.ConsoleHandler.level=FINE

(四)日誌記錄說明

①為一個簡單的應用程式,選擇一個日誌記錄器,並把日誌記錄器命名為與主應用程式包一樣的名字。

②預設的日誌配置將級別等於或高於INFO級別的所有訊息記錄到控制檯上。

③所有級別為INFO、WARNING、SEVERE的訊息都將顯示到控制檯上。因此,最好只將對程式使用者有意義的訊息設定為這幾個級別。