我在前面的「Shit? Happens」一文中提到一個(gè)名為 Shit? 的 RuntimeException,我用它來(lái)幫助找出自己因疏忽而造成的程序錯(cuò)誤,但是這種方式畢竟有點(diǎn)麻煩,而且有一些伴隨而來(lái)的問(wèn)題。使用 Shit? Exception 的缺點(diǎn)包括了:
-
程序員要自行產(chǎn)生并丟出一個(gè)
Shit?
對(duì)象。
?
-
發(fā)生這種問(wèn)題時(shí),通常是很?chē)?yán)重的狀況,不應(yīng)該是
Runtime Exception
,應(yīng)該是
Error
比較恰當(dāng)。
-
?
產(chǎn)品交付給客戶(hù)之前,程序員必須手動(dòng)將程序代碼中所有的這些檢查都刪除,否則對(duì)于執(zhí)行效率會(huì)有不好的影響。
Java? 2 SDK 1.4 新增的 assertion 功能,和 Shit? Exception 的目的一樣,但可以免去 Shit? Exception 的這些缺點(diǎn)。所以我已經(jīng)開(kāi)始改用 assertion,而不再使用 Shit? Exception 了。
你可以在 Java? 程序 method 內(nèi)的任何地方插入 assertion 敘述來(lái)做檢查。Assertion 敘述(statement)的方法是在 assert 這個(gè)關(guān)鍵詞(keyword)之后加上一個(gè)布爾(boolean)判斷式,然后以分號(hào)結(jié)束此敘述。如下例所示:
assert size() == 0;
程序中如果使用到 assertion,編譯時(shí)必須加上「-source 1.4」的選項(xiàng)來(lái)告訴 javac 編譯器,否則 javac 預(yù)設(shè)的狀況是不支持 assertion 語(yǔ)法的。執(zhí)行的時(shí)候必須以「-ea」的選項(xiàng)設(shè)定來(lái)告訴 JRE 必須執(zhí)行 assertion,當(dāng)程序執(zhí)行到 assertion 敘述時(shí),如果布爾判斷式不成立,系統(tǒng)會(huì)丟出 AssertionError 的錯(cuò)誤對(duì)象。如果不用「-ea」選項(xiàng),執(zhí)行時(shí)會(huì)忽略 assertion 敘述不予執(zhí)行。
Assertion 看起來(lái)很神奇,其實(shí)骨子里很平庸。透過(guò)編譯器和 class loader 的合作就可以達(dá)到 assertion 的支持,根本不需要 JVM 在指令集(instruction set)中新增 opcode。舉例來(lái)說(shuō),「assert size() == 0;」這道敘述會(huì)被編譯器當(dāng)成下面的程序代碼來(lái)編譯:
if (ea) {
?? if( size() != 0 ) {
???? throw new AssertionError();
?? }
}
編譯器并會(huì)在此 class 的 bytecode 中插入一個(gè)類(lèi)似下面的私用靜態(tài)合成字段(private static synthetic field):?
private static boolean ea = false;
因?yàn)?span lang="EN-US"> ea(意思是 enable assertion)的默認(rèn)值是 false,所以預(yù)設(shè)情況下是不會(huì)執(zhí)行 assertion 的。如果你透過(guò)「-ea」選項(xiàng)來(lái)執(zhí)行,那么 class loader 會(huì)在加載此 class 的時(shí)候,將 ea 設(shè)為 true,所以就能執(zhí)行 assertion。
執(zhí)行程序時(shí),如果把 assertion 功能打開(kāi),會(huì)造成執(zhí)行時(shí)效率稍微變差,而且不管有沒(méi)有透過(guò)「-ea」來(lái)把 assertion 功能打開(kāi),assertion 的程序代碼都會(huì)一直存在 bytecode 中,會(huì)造成體積的增大,這兩點(diǎn)是使用 assertion 要付出的代價(jià),所以在程序中使用 assertion 的時(shí)機(jī),仍須仔細(xì)斟酌。只要使用得宜,assertion 可以是程序員很好的除錯(cuò)幫手。
商標(biāo)聲名:
Java? is a trademark of Sun Microsystems.
Shit? is a trademark of Jerry Tsai.
?