java之a(chǎn)ssert關(guān)鍵字用法案例詳解
Java2在1.4中新增了一個(gè)關(guān)鍵字:assert。在程序開發(fā)過程中使用它創(chuàng)建一個(gè)斷言(assertion)。,它的語(yǔ)法形式有如下所示的兩種形式:
1、assert condition;
這里condition是一個(gè)必須為真(true)的表達(dá)式。如果表達(dá)式的結(jié)果為true,那么斷言為真,并且無任何行動(dòng)
如果表達(dá)式為false,則斷言失敗,則會(huì)拋出一個(gè)AssertionError對(duì)象。這個(gè)AssertionError繼承于Error對(duì)象,
而Error繼承于Throwable,Error是和Exception并列的一個(gè)錯(cuò)誤對(duì)象,通常用于表達(dá)系統(tǒng)級(jí)運(yùn)行錯(cuò)誤。
2、asser condition:expr;
這里condition是和上面一樣的,這個(gè)冒號(hào)后跟的是一個(gè)表達(dá)式,通常用于斷言失敗后的提示信息,說白了,它是一個(gè)傳到AssertionError構(gòu)造函數(shù)的值,如果斷言失敗,該值被轉(zhuǎn)化為它對(duì)應(yīng)的字符串,并顯示出來。
用一個(gè)例子說明一下:
public class Test {
public static void main(String[] args) {
System.out.println("start");
assert true;
System.out.println("go on");
assert false:"stop";
System.out.println("end");
}
}
這里有一個(gè)測(cè)試類,通過之前簡(jiǎn)單的語(yǔ)法介紹后,可以這樣簡(jiǎn)單的理解這個(gè)例子:
當(dāng)程序運(yùn)行到assert true這一句時(shí),condition為true,系統(tǒng)會(huì)繼續(xù)執(zhí)行下去。而后執(zhí)行到 assert false:"stop"的時(shí)候,由于condition=false,系統(tǒng)會(huì)拋出AssertionError。
但是試試上是不是這樣的呢?
看看運(yùn)行結(jié)果就知道了
start
go on
end
這個(gè)運(yùn)行結(jié)果和我們一開始的預(yù)期不一致,問題出在哪里了?
原來java的斷言與C語(yǔ)言中的斷言還有有些不同的地方。
Java的assertion的開啟也和C語(yǔ)言不太一樣,在C語(yǔ)言中,assertion的開啟是在編譯時(shí)候決定的。當(dāng)我們使用debug方式編譯程序時(shí)候,assertion被開啟,而使用release方式編譯時(shí)候,assertion自動(dòng)被關(guān)閉。 而Java的assertion卻是在運(yùn)行的時(shí)候進(jìn)行決定的。其實(shí),這兩種方式是各有優(yōu)缺點(diǎn)。如果采用編譯時(shí)決定方式,開發(fā)人員將處理兩種類型的目標(biāo)碼,debug版本和release版本,這加大了文檔管理的難度,但是提高了代碼的運(yùn)行效率。 Java采用運(yùn)行時(shí)決定的方式,這樣所有的assertion信息將置于目標(biāo)代碼 中,同一目標(biāo)代碼可以選擇不同方式運(yùn)行,增強(qiáng)目標(biāo)代碼的靈活性,但是它將犧牲因?yàn)閍ssertion而引起一部分性能損失。
說直白一點(diǎn)就是:assert關(guān)鍵字需要在運(yùn)行時(shí)候顯式開啟才能生效,否則你的斷言就沒有任何意義。
如果需要觀察斷言的運(yùn)行情況,就需要打開系統(tǒng)類的assertion功能 ,我們可使用-esa參數(shù)打開,使用 -dsa參數(shù)關(guān)閉。 -esa和-dsa的全名為-enablesystemassertions和 -disenablesystemassertions,全名和縮寫名有同樣的功能。
我們還是用剛剛那個(gè)測(cè)試方法,再執(zhí)行試試看:

當(dāng)我們只是通過java命令編譯、執(zhí)行測(cè)試方法時(shí),并沒有執(zhí)行assert語(yǔ)句;然而通過java -ea Test命令顯示打開assertion功能后,發(fā)現(xiàn)系統(tǒng)確實(shí)執(zhí)行了assert語(yǔ)句。
另外,我們注意到體統(tǒng)拋出的是AssertionError,作為Error的一個(gè)子類,而不是 RuntimeException。Error代表一些異常的錯(cuò)誤,通常是不可以恢復(fù)的,而 RuntimeException強(qiáng)調(diào)該錯(cuò)誤在運(yùn)行時(shí)才發(fā)生的特點(diǎn)。AssertionError通常為非常關(guān)鍵的錯(cuò)誤,這些錯(cuò)誤往往是不容易恢復(fù)的,而且assertion機(jī)制也不鼓勵(lì)程序員對(duì)這種錯(cuò)誤進(jìn)行恢復(fù)。
通過這個(gè)實(shí)驗(yàn)的現(xiàn)象,可以引發(fā)一些思考:
1.assert需要顯示的開啟生效才有作用。
這就意味著你如果使用IDE工具編碼,調(diào)試運(yùn)行時(shí)候會(huì)有一定的麻煩,因?yàn)榛旧蟡ava IDE都是沒有開啟斷言功能的。并且,對(duì)于Java Web應(yīng)用,程序代碼都是部署在容器里面,你沒法直接去控制程序的運(yùn)行,如果一定要開啟-ea的開關(guān),則需要更改Web容器的運(yùn)行配置參數(shù)。這對(duì)程序的移植和部署都帶來很大的不便。
2.assert斷言失敗將面臨程序的退出。這在一個(gè)生產(chǎn)環(huán)境下的應(yīng)用是絕不能容忍的。一般都是通過異常處理來解決程序中潛在的錯(cuò)誤。但是使用斷言就很危險(xiǎn),一旦失敗系統(tǒng)就掛了。
3.即使處理了Error,如果斷言的代碼嵌入到業(yè)務(wù)流程中,一旦assert失效,也就改變了正常的業(yè)務(wù)邏輯(如果condition中加入了賦值等操作)。
我想可能就是這些原因?qū)е缕綍r(shí)的java開發(fā)中幾乎不會(huì)用到assert關(guān)鍵字,即便如此,JDK中還是存在不少使用assert的地方,比方說java.util.Locale類等
4.是不是可用通過封裝一些方法,自己來完成斷言的功能,既使用簡(jiǎn)單,又方便理解。至少我是這樣做的。
到此這篇關(guān)于java之a(chǎn)ssert關(guān)鍵字用法案例詳解的文章就介紹到這了,更多相關(guān)java之a(chǎn)ssert關(guān)鍵字用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)圖片上傳及本地訪問
在SpringBoot項(xiàng)目中,處理靜態(tài)文件訪問尤其是實(shí)時(shí)更新的文件如商品圖片,可通過配置WebMvcConfig將本地文件映射到URL路徑上,以解決重啟項(xiàng)目才能訪問文件的問題,本文詳解如何保存和訪問這些文件,幫助開發(fā)者優(yōu)化項(xiàng)目文件管理2022-09-09
SpringBoot中實(shí)現(xiàn)定時(shí)任務(wù)的4種方式詳解
這篇文章主要介紹了SpringBoot中實(shí)現(xiàn)定時(shí)任務(wù)的4種方式詳解,在Springboot中定時(shí)任務(wù)是一項(xiàng)經(jīng)常能用到的功能,實(shí)現(xiàn)定時(shí)任務(wù)的方式有很多,今天來介紹常用的幾種,需要的朋友可以參考下2023-11-11
Java編程實(shí)現(xiàn)軌跡壓縮之Douglas-Peucker算法詳細(xì)代碼
這篇文章主要介紹了Java編程實(shí)現(xiàn)軌跡壓縮之Douglas-Peucker算法詳細(xì)代碼,具有一定借鑒價(jià)值,需要的朋友可以參考。2017-11-11
Selenium Webdriver實(shí)現(xiàn)截圖功能的示例
今天小編就為大家分享一篇Selenium Webdriver實(shí)現(xiàn)截圖功能的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05
解決dubbo啟動(dòng)報(bào)服務(wù)注冊(cè)失敗Failed?to?register?dubbo
這篇文章主要介紹了解決dubbo啟動(dòng)報(bào)服務(wù)注冊(cè)失敗Failed?to?register?dubbo問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java計(jì)算Date類時(shí)間差實(shí)例代碼演示
最近工作中遇到需要計(jì)算時(shí)間差,這里給大家總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于Java計(jì)算Date類時(shí)間差的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12

