rosial

          lost memory
          數據加載中……

          《爪哇夜未眠》- 系統篇 - 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.

          ?

          posted on 2006-07-10 14:49 rosial 閱讀(237) 評論(0)  編輯  收藏 所屬分類: 蔡學鏞

          主站蜘蛛池模板: 昌邑市| 玉树县| 徐闻县| 金湖县| 武乡县| 额济纳旗| 满洲里市| 久治县| 徐闻县| 临武县| 武川县| 乐安县| 越西县| 玉门市| 宝山区| 常山县| 池州市| 宁海县| 徐汇区| 辽阳县| 洞口县| 卢氏县| 勃利县| 五峰| 金堂县| 安塞县| 定安县| 西峡县| 化隆| 曲松县| 句容市| 会宁县| 会同县| 抚顺县| 梁山县| 昆明市| 尉犁县| 芮城县| 广德县| 洪江市| 罗江县|