程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Merlin的魔力: 使用斷言

Merlin的魔力: 使用斷言

編輯:關於JAVA

斷言功能是 Java 1.4 發行版所具有的為人熱切期盼的一項新功能。您可以將該功能看作是異常處理的一種高級形式。斷言表示為一些布爾表達式,程序員相信在程序中的某個特定點該表達式的值為真。例如,程序員可能會在程序中包含斷言,使您永遠也不會到達 switch 語句中的 default 條件。

由於可以在任何時候啟用或禁用斷言驗證,因此可以在測試時啟用斷言驗證而部署時禁用斷言驗證。同樣,程序投入運行後,最終用戶在碰到問題時可以重新啟用斷言。

在本專欄文章中,通過演示兩種不同的方式來啟用和禁用斷言以便優化代碼測試和性能,我將向您講述一些有關向代碼中添加斷言的基本知識。

斷言關鍵字

斷言檢查就象異常處理,但是當斷言失敗時,卻不會拋出異常,而會拋出一個 AssertionError 。象所有錯誤一樣,從斷言故障中恢復(如果不是不可能的話)就是很困難的,因為這樣的故障表明程序狀態已偏離正常操作參數。

使用斷言的兩個基本構造如下:

assert booleanExpression;
assert booleanExpression : message;

注意,可選的消息(message)將作為錯誤拋出的結果顯示出來。

可以將斷言語句作為方法的前置條件或後置條件來添加。也可以建立布爾表達式以調用方法。同樣,您可能希望向 if 塊中的 else 條件添加斷言,這裡已經設置了該條件,或者向 switch 語句中的缺省情況中添加斷言,使缺省情況永遠不可能到達。 assert 關鍵字的唯一限制在於它必須位於可執行塊中。不能將斷言同實例的類變量聲明一塊使用,但卻可以將其置於任何方法內。

啟用斷言

如果您想使用斷言,那麼您必須使用一些專門的命令行選項來編譯並運行程序。由於編譯器運行於 1.3 兼容模式,因此您必須顯式地要求運行在 1.4 模式下。要編譯帶有斷言的程序,只需向 Java 編譯器傳遞 -source 1.4 設置。缺省情況下,會禁用斷言檢查,因此在運行時您也要顯式地啟用這一功能。請使用 -enableassertions 選項或更短的 -ea 選項來啟用斷言檢查。

下面的簡單示例向您介紹了向程序中添加斷言檢查的一些必要步驟。它檢查命令行參數的數目,如果值不為 0 時,則報告問題:

public class AssertTest {
  public static void main(String args[]) {
   assert args.length == 0 : args.length + " != 0";
   System.out.println(args.length);
  }
}

確保按如下所示使用 -source 選項來編譯該程序:

javac -source 1.4 AssertTest.java

要測試該程序,只需運行該程序並傳遞命令行參數:

java AssertTest 1 2 3 4

因為該程序是用來顯示參數的數目,所以該測試程序將顯示四。由於在缺省情況下禁用了斷言檢查,因此不會檢測到任何斷言錯誤。

現在,請帶有啟用斷言檢查運行該程序:

java -ea AssertTest 1 2 3 4

帶啟用斷言檢查運行程序產生下面的錯誤報告:

Exception in thread "main" java.lang.AssertionError: 1 != 0
     at AssertTest.main(AssertTest.java:3)

這就是整個斷言功能的實質。這裡,最難的部分是確定將 assert 關鍵字放在何處以及條件是什麼。

其它使用斷言的方法

對於整個程序,雖然 -ea 選項是一種啟用斷言的簡易方法,但也可以使用其它選項。另外, -ea 不能用於系統類;由於那個原因,需要使用 -enablesystemassertions ,或者更簡單些,使用 -esa 。

要對整個包樹(即包和子包)啟用斷言,只需在 -ea 選項後面加上一個冒號,包的名稱和一個省略號(...)。例如,下面的語法將對 net.zukowski.ibm 包及其所有的子包啟用斷言檢查:

java -ea:net.zukowski.ibm... EclipseTest

對於特定類,需要指定完整的類名而不是在包名稱之後加省略號。

如果希望對包的整個集合啟用斷言檢查,而不是某個類或包(樹)啟用斷言檢查,則 -da 標記就能滿足這一要求(“ -da ”是 -disableassertions 的縮寫)。只需列出啟用和禁用選項,您只需做這些。例如,下面的語法對 net.zukowski.ibm 包啟用斷言檢查,但不對 net.zukowski.ibm.BeanUtils 類啟用斷言檢查:

java -ea:net.zukowski.ibm... -da:net.zukowski.ibm.BeanUtils EclipseTest

通過編程啟用斷言

除了從命令行啟用斷言檢查之外,您也可以通過編程啟用(或禁用)檢查。由於這僅影響將來裝入的類,因此不能隨意地關閉或打開它。

類的 ClassLoader 使用下面四種方法控制斷言的啟用和禁用:

public void setDefaultAssertionStatus(boolean enabled) : 該方法設置由類裝入器裝入的包和類的缺省狀態。可以通過設置特定的包和類選項來覆蓋該設置。

public void setPackageAssertionStatus(String packageName, boolean enabled) :要覆蓋包和其所有的子包的狀態,傳入包名和啟用狀態。

public void setClassAssertionStatus(String className, boolean enabled) :要覆蓋特定類的狀態,傳入全限定類名和啟用狀態。

public void clearAssertionStatus() :該方法將所有包和類的設置重設為 false,然後將類裝入器也重設為 false。

要獲取類的類裝入器,調用 Class 對象的 getClassLoader() 方法。對非靜態方法使用以下命令:

ClassLoader loader = getClass().getClassLoader();

對於靜態方法,不能調用 getClass() ,因為沒有實例,所以只需把 .class 添加到當前類名的後面,如下所示:

ClassLoader loader = EclipseTest.class.getClassLoader();

請記住這僅影響更改之後裝入的類。在大多數情況下,您會發現您是從命令行啟用斷言。

小結

您掌握了吧。這就是 Java 1.4 斷言功能。有關在何處使用斷言這方面的提示,請參閱 參考資料中列出的正式文檔中的 Usage Notes部分。使用斷言時要記住的關鍵是可以選擇性地啟用斷言;因此,除了時間差異之外,它們不會有任何副作用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved