首頁
中文書目錄
原文書目錄
 站內快速搜尋
資源中心
Book Series
Special Interest













■好消息,歐萊禮書籍已重新鋪貨至各大書局及網路書店,歡迎讀者選購       ■歡迎各院校採用歐萊禮書籍,學校團購請洽校園服務團隊

[技術短文]

Shit™ Happens, Part II


我在前面的「Shit™ Happens」一文中提到一個名為 Shit™ 的 RuntimeException,我用它來幫助找出自己因疏忽而造成的程式錯誤,但是這種方式畢竟有點麻煩,而且有一些伴隨而來的問題。使用 Shit™ Exception 的缺點包括了:
  1. 程式員要自行產生並丟出一個 Shit™ 物件。 
  2. 發生這種問題時,通常是很嚴重的狀況,不應該是 Runtime Exception,應該是 Error 比較恰當。
  3.  產品交付給客戶之前,程式員必須手動將程式碼中所有的這些檢查都刪除,否則對於執行效率會有不好的影響。
Java™ 2 SDK 1.4 新增的 assertion 功能,和 Shit™ Exception 的目的一樣,但可以免去 Shit™ Exception 的這些缺點。所以我已經開始改用 assertion,而不再使用 Shit™ Exception 了。

你可以在 Java™ 程式 method 內的任何地方插入 assertion 敘述來做檢查。Assertion 敘述(statement)的方法是在 assert 這個關鍵字(keyword)之後加上一個布林(boolean)判斷式,然後以分號結束此敘述。如下例所示:
assert size() == 0;
程式中如果使用到 assertion,編譯時必須加上「-source 1.4」的選項來告訴 javac 編譯器,否則 javac 預設的狀況是不支援 assertion 語法的。執行的時候必須以「-ea」的選項設定來告訴 JRE 必須執行 assertion,當程式執行到 assertion 敘述時,如果布林判斷式不成立,系統會丟出 AssertionError 的錯誤物件。如果不用「-ea」選項,執行時會忽略 assertion 敘述不予執行。

Assertion 看起來很神奇,其實骨子裡很平庸。透過編譯器和 class loader 的合作就可以達到 assertion 的支援,根本不需要 JVM 在指令集(instruction set)中新增 opcode。舉例來說,「assert size() == 0;」這道敘述會被編譯器當成下面的程式碼來編譯:
if (ea) {
   if( size() != 0 ) {
     throw new AssertionError();
   }
}

編譯器並會在此 class 的 bytecode 中插入一個類似下面的私用靜態合成欄位(private static synthetic field): 
private static boolean ea = false;
因為 ea(意思是 enable assertion)的預設值是 false,所以預設情況下是不會執行 assertion 的。如果你透過「-ea」選項來執行,那麼 class loader 會在載入此 class 的時候,將 ea 設為 true,所以就能執行 assertion。

執行程式時,如果把 assertion 功能打開,會造成執行時效率稍微變差,而且不管有沒有透過「-ea」來把 assertion 功能打開,assertion 的程式碼都會一直存在 bytecode 中,會造成體積的增大,這兩點是使用 assertion 要付出的代價,所以在程式中使用 assertion 的時機,仍須仔細斟酌。只要使用得宜,assertion 可以是程式員很好的除錯幫手。

商標聲名:
Java™ is a trademark of Sun Microsystems.
Shit™ is a trademark of Jerry Tsai.

本文作者:蔡學鏞
張貼日期:8/31/01

| 首頁 | 聯絡我們 |
© 2009, O'Reilly Media, Inc. Taiwan Branch