java之assert關鍵字用法案例詳解

Java2在1.4中新增瞭一個關鍵字:assert。在程序開發過程中使用它創建一個斷言(assertion)。,它的語法形式有如下所示的兩種形式:

1、assert condition;
這裡condition是一個必須為真(true)的表達式。如果表達式的結果為true,那麼斷言為真,並且無任何行動
如果表達式為false,則斷言失敗,則會拋出一個AssertionError對象。這個AssertionError繼承於Error對象,
而Error繼承於Throwable,Error是和Exception並列的一個錯誤對象,通常用於表達系統級運行錯誤。

2、asser condition:expr;
這裡condition是和上面一樣的,這個冒號後跟的是一個表達式,通常用於斷言失敗後的提示信息,說白瞭,它是一個傳到AssertionError構造函數的值,如果斷言失敗,該值被轉化為它對應的字符串,並顯示出來。

用一個例子說明一下:

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");
    }
}

這裡有一個測試類,通過之前簡單的語法介紹後,可以這樣簡單的理解這個例子:

當程序運行到assert true這一句時,condition為true,系統會繼續執行下去。而後執行到 assert false:”stop”的時候,由於condition=false,系統會拋出AssertionError。

但是試試上是不是這樣的呢?

看看運行結果就知道瞭

start
go on
end

這個運行結果和我們一開始的預期不一致,問題出在哪裡瞭?

原來java的斷言與C語言中的斷言還有有些不同的地方。

Java的assertion的開啟也和C語言不太一樣,在C語言中,assertion的開啟是在編譯時候決定的。當我們使用debug方式編譯程序時候,assertion被開啟,而使用release方式編譯時候,assertion自動被關閉。  而Java的assertion卻是在運行的時候進行決定的。其實,這兩種方式是各有優缺點。如果采用編譯時決定方式,開發人員將處理兩種類型的目標碼,debug版本和release版本,這加大瞭文檔管理的難度,但是提高瞭代碼的運行效率。  Java采用運行時決定的方式,這樣所有的assertion信息將置於目標代碼 中,同一目標代碼可以選擇不同方式運行,增強目標代碼的靈活性,但是它將犧牲因為assertion而引起一部分性能損失。    

說直白一點就是:assert關鍵字需要在運行時候顯式開啟才能生效,否則你的斷言就沒有任何意義。

如果需要觀察斷言的運行情況,就需要打開系統類的assertion功能 ,我們可使用-esa參數打開,使用 -dsa參數關閉。  -esa和-dsa的全名為-enablesystemassertions和 -disenablesystemassertions,全名和縮寫名有同樣的功能。

我們還是用剛剛那個測試方法,再執行試試看:

當我們隻是通過java命令編譯、執行測試方法時,並沒有執行assert語句;然而通過java -ea Test命令顯示打開assertion功能後,發現系統確實執行瞭assert語句。

另外,我們註意到體統拋出的是AssertionError,作為Error的一個子類,而不是 RuntimeException。Error代表一些異常的錯誤,通常是不可以恢復的,而 RuntimeException強調該錯誤在運行時才發生的特點。AssertionError通常為非常關鍵的錯誤,這些錯誤往往是不容易恢復的,而且assertion機制也不鼓勵程序員對這種錯誤進行恢復。

通過這個實驗的現象,可以引發一些思考:

1.assert需要顯示的開啟生效才有作用。

這就意味著你如果使用IDE工具編碼,調試運行時候會有一定的麻煩,因為基本上java IDE都是沒有開啟斷言功能的。並且,對於Java Web應用,程序代碼都是部署在容器裡面,你沒法直接去控制程序的運行,如果一定要開啟-ea的開關,則需要更改Web容器的運行配置參數。這對程序的移植和部署都帶來很大的不便。

2.assert斷言失敗將面臨程序的退出。這在一個生產環境下的應用是絕不能容忍的。一般都是通過異常處理來解決程序中潛在的錯誤。但是使用斷言就很危險,一旦失敗系統就掛瞭。

3.即使處理瞭Error,如果斷言的代碼嵌入到業務流程中,一旦assert失效,也就改變瞭正常的業務邏輯(如果condition中加入瞭賦值等操作)。

我想可能就是這些原因導致平時的java開發中幾乎不會用到assert關鍵字,即便如此,JDK中還是存在不少使用assert的地方,比方說java.util.Locale類等

4.是不是可用通過封裝一些方法,自己來完成斷言的功能,既使用簡單,又方便理解。至少我是這樣做的。

到此這篇關於java之assert關鍵字用法案例詳解的文章就介紹到這瞭,更多相關java之assert關鍵字用法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: