assert

 

Java陷阱之assert關鍵字
 
1、概述
 
在C和C++語言中都有assert關鍵,表示斷言。
在Java中,一樣也有assert關鍵字,表示斷言,用法和含義都差很少。
 
2、語法
 
在Java中,assert關鍵字是從JAVA SE 1.4 引入的,爲了不和老版本的Java代碼中使用了assert關鍵字致使錯誤,Java在執行的時候默認是不啓動斷言檢查的(這個時候,全部的斷言語句都將忽略!),若是要開啓斷言檢查,則須要用開關-enableassertions或-ea來開啓。
 
assert關鍵字語法很簡單,有兩種用法:
 
一、assert <boolean表達式>
若是<boolean表達式>爲true,則程序繼續執行。
若是爲false,則程序拋出AssertionError,並終止執行。
 
二、assert <boolean表達式> : <錯誤信息表達式>
若是<boolean表達式>爲true,則程序繼續執行。
若是爲false,則程序拋出java.lang.AssertionError,並輸入<錯誤信息表達式>。
 
3、應用實例
 
下面給出一個例子,經過例子說明其用法:
 
public class AssertFoo {
    public static void main(String args[]) {
        // 斷言 1 結果爲 true ,則繼續往下執行
        assert true ;
        System. out .println( " 斷言 1 沒有問題, Go " );
        System. out .println( "\n-----------------\n" );
        // 斷言 2 結果爲 false,程序終止
        assert false : " 斷言失敗,此表達式的信息將會在拋出異常的時候輸出! " ;
        System. out .println( " 斷言 2 沒有問題, Go " );
    }
}
 
保存代碼到C:\AssertFoo.java,而後按照下面的方式執行,查看控制檯輸出結果:
 
一、編譯程序:
C:\>javac AssertFoo.java
 
二、默認執行程序,沒有開啓-ea開關:
C:\>java AssertFoo
斷言1沒有問題,Go!
 
-----------------
 
斷言2沒有問題,Go!
 
三、開啓-ea開關,執行程序:
C:\>java -ea AssertFoo
斷言1沒有問題,Go!
 
-----------------
 
Exception in thread "main" java.lang.AssertionError: 斷言失敗,此表達式的信息將
會在拋出異常的時候輸出!
        at AssertFoo.main(AssertFoo.java:10)
 
4、陷阱
 
assert關鍵字用法簡單,可是使用assert每每會讓你陷入愈來愈深的陷阱中。應避免使用。筆者通過研究,總結了如下緣由:
 
一、assert關鍵字須要在運行時候顯式開啓才能生效,不然你的斷言就沒有任何意義。而如今主流的Java IDE工具默認都沒有開啓-ea斷言檢查功能。這就意味着你若是使用IDE工具編碼,調試運行時候會有必定的麻煩。而且,對於Java Web應用,程序代碼都是部署在容器裏面,你無法直接去控制程序的運行,若是必定要開啓-ea的開關,則須要更改Web容器的運行配置參數。這對程序的移植和部署都帶來很大的不便。
 
二、用assert代替if是陷阱之二。assert的判斷和if語句差很少,但二者的做用有着本質的區別:assert關鍵字本意上是爲測試調試程序時使用的,但若是不當心用assert來控制了程序的業務流程,那在測試調試結束後去掉assert關鍵字就意味着修改了程序的正常的邏輯。
 
三、assert斷言失敗將面臨程序的退出。這在一個生產環境下的應用是毫不能容忍的。通常都是經過異常處理來解決程序中潛在的錯誤。可是使用斷言就很危險,一旦失敗系統就掛了。

 

 

 

--------------------------------------------------------------------------------------------------------- java

assert 有很大的用處
首先能夠用在單元測試代碼中。junit侵入性是很強的,若是整個工程大量的代碼都使用了junit,就難以去掉或者是選擇另一個框架。若是單元測試代碼不少,而且想複用這些單元測試案例,應該選擇assert而不是junit,便於使用別的單元測試框架,好比TestNG。同理正式的功能代碼根本就不該該出現Junit,應該使用assert.

assert主要適合在基類,框架類,接口類,核心代碼類,工具類中。換言之,當你的代碼的調用者是另一個程序員寫得業務代碼,或者是另一個子系統時,就頗有必要使用它。好比你作了一個快速排序的算法

public static List<int> quickSort(List<int> list){
    assert list != null;
    // 申請臨時空間
    //開始排序
    for(int i : list){
          //
    }
}

這種狀況下,若是不檢查傳入參數的正確性,會拋出一個莫名其妙的空指針錯誤。你的調用者可能並不清楚你代碼的細節,在一個系統的深處調試一個空指針錯誤是很浪費時間的。就應該直接明確的告訴你的調用者是傳入的參數有問題。不然他會懷疑你的代碼有BUG。使用assert能夠避免兩個程序員之間互相指責對方寫的代碼有問題。

assert適用那些你知道具體是什麼錯誤,你和你的調用者已經約定應該由你的調用者去排除或檢查的錯誤。你經過一個斷言告訴你的調用者。assert不適用那些外部系統形成的錯誤,好比用戶輸入數據的錯誤,某個外部文件格式錯誤。這些錯誤不是你的調用者而是用戶形成的,甚至於不屬於異常,由於出現輸入錯誤和文件格式錯誤是常常的,這些錯誤應該由業務代碼去檢查。

assert比較適合於被頻繁調用的 基類,框架代碼,工具類,核心代碼,接口代碼中,這正是它在運行時被去掉的緣由。測試代碼應該在測試階段開啓-ea參數,便於對系統深處的核心代碼作仔細的測試。

Java較少使用assert的緣由是Java有很完整的OO體系,強制類型轉換出現得較少,因此不須要相似c那樣須要頻繁的檢查指針的類型是否正確,指針是否爲空。同時Java也不多直接管理內存或緩衝區,因此不須要頻繁的檢查傳入的緩衝區是否爲空或者是已經越界。

但使用好assert有助於提升框架代碼的正確性和減小框架代碼的使用者的調試時間。 程序員

------------------------------------------------------------------------------------------------------- 算法

 

assert要達到的目的是讓程序員方便的發現本身的邏輯錯誤,而且不影響程序的效率。assert所發現的錯誤,是徹底不該該出現的,是不能用異常代替的。異常,那是系統所容許的,或者是系統不可控的「錯誤」,它不是程序員的邏輯問題。

assert應該是開發階段打開,而在發佈後關閉。

加入assert,是java的一個進步,要正確認識assert! 框架

相關文章
相關標籤/搜索