相信學(xué)過(guò)c,c++的朋友一定不會(huì)對(duì)斷言感到陌生。下面介紹一下斷言在JAVA中的使用,JAVA是從JDK1.4才開始支持?jǐn)嘌缘模ㄌ砑恿岁P(guān)鍵字assert),請(qǐng)注意老版的JRE不支持。
斷言概述
??編寫代碼時(shí),我們總是會(huì)做出一些假設(shè),斷言就是用于在代碼中
捕捉這些假設(shè)??可以將斷言看作是
異常處理的一種高級(jí)形式??斷言表示為一些布爾表達(dá)式,程序員相信在程序中的某個(gè)特定點(diǎn)該表達(dá)式值為真
??可以在任何時(shí)候啟用和禁用斷言驗(yàn)證,因此可以在測(cè)試時(shí)啟用斷言而在部署時(shí)禁用斷言。同樣,程序投入運(yùn)行后,最終用戶在遇到問(wèn)題時(shí)可以重新起用斷言。
??使用斷言可以創(chuàng)建更穩(wěn)定,品質(zhì)更好且易于除錯(cuò)的代碼
??當(dāng)需要在一個(gè)值為FALSE時(shí)中斷當(dāng)前操作的話,可以使用斷言
??單元測(cè)試必須使用斷言(Junit/JunitX)
??除了類型檢查和單元測(cè)試外,斷言還提供了一種確定個(gè)種特性是否在程序中得到維護(hù)的極好的方法
??使用斷言使我們向
按契約式設(shè)計(jì)更近了一部
常見(jiàn)的斷言特性
??前置條件斷言:代碼執(zhí)行之前必須具備的特性
??后置條件斷言:代碼執(zhí)行之后必須具備的特性
??前后不變斷言:代碼執(zhí)行前后不能變化的特性
斷言使用方式
??斷言可以有兩種形式
??1.assert?Expression1
??2.assert?Expression1:Expression2
??其中Expression1應(yīng)該總是一個(gè)布爾值,Expression2是斷言失敗時(shí)輸出的失敗消息的字符串。如果Expression1為假,則拋出一個(gè)?AssertionError,這是一個(gè)錯(cuò)誤,而不是一個(gè)異常,也就是說(shuō)是一個(gè)不可控制異常(unchecked?Exception),AssertionError由于是錯(cuò)誤,所以可以不捕獲,但不推薦這樣做,因?yàn)槟菢訒?huì)使你的系統(tǒng)進(jìn)入不穩(wěn)定狀態(tài)。
起用斷言
??斷言在默認(rèn)情況下是關(guān)閉的,要在編譯時(shí)啟用斷言,需要使用source1.4標(biāo)記?既javac?source1.4?Test.java?,在運(yùn)行時(shí)啟用斷言需要使用?-ea參數(shù)?。要在系統(tǒng)類中啟用和禁用斷言可以使用?-esa?和?-dsa參數(shù)。
??
例如:
public class AssertExampleOne{
?? public AssertExampleOne(){}
?? public static void main(String args[]){
????? int x=10;
????? System.out.println("Testing Assertion that x==100");
????? assert x==100:"Out assertion failed!";
????? System.out.println("Test passed!");
?? }
}
如果編譯時(shí)未加?-source1.4,則編譯通不過(guò)
在執(zhí)行時(shí)未加?-ea?時(shí)輸出為
Testing?Assertion?that?x==100
Test?passed
jre忽略了斷言的就代碼,而使用了該參數(shù)就會(huì)輸出為
Testing?Assertion?that?x==100
Exception?in?thread?"main"?java.lang.AssertionError:?Out?assertion?failed!
????????at?AssertExampleOne.main(AssertExampleOne.java:6)
斷言的副作用
??由于程序員的問(wèn)題,斷言的使用可能會(huì)帶來(lái)副作用?,例如:
??boolean?isEnable=false;
??//...
??assert?isEnable=true;
??這個(gè)斷言的副作用是因?yàn)樗薷牧顺绦蛑凶兞康闹挡⑶椅磼伋鲥e(cuò)誤,這樣的錯(cuò)誤如果不細(xì)心的檢查是很難發(fā)現(xiàn)的。但是同時(shí)我們可以根據(jù)以上的副作用得到一個(gè)有用的特性,根據(jù)它來(lái)測(cè)試斷言是否打開。
?public?class?AssertExampleTwo{
???public?static?void?main(String?args[]){
?????boolean?isEnable=false;
?????//...
?????assert?isEnable=true;
?????if(isEnable==false){
???????throw?new?RuntimeException("Assertion?shoule?be?enable!");
?????}
???}
}
何時(shí)需要使用斷言
??1.可以在預(yù)計(jì)正常情況下程序不會(huì)到達(dá)的地方放置斷言?:assert?false
??2.斷言可以用于檢查傳遞給私有方法的參數(shù)。(對(duì)于公有方法,因?yàn)槭翘峁┙o外部的接口,所以必須在方法中有相應(yīng)的參數(shù)檢驗(yàn)才能保證代碼的健壯性)
??3.使用斷言測(cè)試方法執(zhí)行的前置條件和后置條件
??4.使用斷言檢查類的不變狀態(tài),確保任何情況下,某個(gè)變量的狀態(tài)必須滿足。(如age屬性應(yīng)大于0小于某個(gè)合適值)
什么地方不要使用斷言
??斷言語(yǔ)句不是永遠(yuǎn)會(huì)執(zhí)行,可以屏蔽也可以啟用
因此:
??1.不要使用斷言作為公共方法的參數(shù)檢查,公共方法的參數(shù)永遠(yuǎn)都要執(zhí)行
??2.斷言語(yǔ)句不可以有任何邊界效應(yīng),不要使用斷言語(yǔ)句去修改變量和改變方法的返回值
參考:
http://jcp.org/en/jsr/detail?id=41
http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html
http://www-128.ibm.com/developworkers/cn/java/jdiag0723/
http://www-128.ibm.com/developworkers/cn/java/jmerlin/part9/