之前在學習java原始碼時,發現了assert這個不常用的關鍵字。下面直接來介紹下這個關鍵字的使用。
assert是什麼?
它是jdk1.4之後新增加的關鍵字,沒了。
assert的作用是什麼?
assert在許多程式語言中的用途都是斷言。
但是什麼是斷言呢?
只是簡單的判斷一下布林表達式是否為真麼?
好,帶著這些問題,我們直入正題吧。
assert vt vt. 維護,堅持;斷言;主張;聲稱。
透過查看assert的翻譯,我們可以看到assert有主張、維護和堅持的意思。
也就是說,assert後邊所跟的條件(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )必須滿足,必須維護,否則就會出現錯誤。
assert的使用
assert的使用包含兩塊內容
(1)關鍵字在程式碼中的使用:
assert 有兩種使用方法:
〜〜〜〜Sasserd:olleans;一個布林表達式。
如果表達式的值為true,那麼就認為當前條件符合要求,繼續執行業務代碼。
如果表達式的值為false,那麼久認為當前條件不符合要求,立即拋出AssertionError的錯誤。
AssertionError extends Error extends Throwable.Throw這個類,平常使用的相對較少,它還有一個子類叫做Exception。 Error和Exception一樣,均屬於系統不應該試圖捕捉的嚴重問題。
2)assert BooleanCondition:Excepiton
assert後邊跟一個布林表達式,同時再跟一個返回值為基本類型的表達式。
當表達式為true時,則繼續運(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )行剩餘業務代碼,不會執行‘:’後邊的表達式。
當表達式為false時,則會執行‘:’後邊的表達式,並將結果放置在AssertionError異常中,並拋出。
下面給一個程式碼範例:
public class assertStudy { public static void main(String args[]) { assert 1 == 1; System.out.println("A Go!"); System.out.println("\n-----------------------------------------------\n"); assert 1 != 1 : "Wrong"; System.out.println("B Go!"); } }
(2)關鍵字的有效性
在上述的assert處加入斷點,Debug調試時,發現斷點處根本沒有停頓,而是直接跳過了。
為什麼會這樣呢?這是因為assert關鍵字是受java啟動項目配置的。
在啟動時 需要透過-ea將開關開啟
java -ea assertStudy
這樣我們就會看到assert行的斷點生效了(預設是不開啟的)。
而
java -da assertStudy,這樣assert就失效了
eclipse中開啟關鍵字有效性的方法如下:
選擇選單:Run--->Run...--->選擇Arguments選項卡
在VM arguments文字方塊中輸入:-ea 注意中間沒有空格,如果輸入-da 表示禁止斷言
(如果找不到以上的路徑,請依次開(防盜連接:本文首發自http://www .cnblogs.com/jilodream/ )啟蒙斷言: windows -> Preferences -> Java ->Installed JREs -> 點擊正在使用的JDK -> Edit -> Default VM Arguments 文字方塊中輸入:-ea)
assert的必要性透過assert的敘述,我們發現他和java中的if非常相似。那為什麼java還要加這樣的一個關鍵字呢?並且還是在jdk1.4這樣一個後續版本中加入呢? 注意看assert的描述和拋出的異常是個Error。 即assert本意是對環境中,在正常使用的情況下,不會出現問題的條件判斷。這些程式碼常常出現在基底類別、框架類別、工具類別等核心程式碼中。而在這些程式碼的正常運作中,是不會出現參數異常(防盜連線:本文首發自http://www.cnblogs.com/jilodream/ )的場景的。可是一旦透過反射,動態代理等方式使某些關鍵值發生了改變,就會導致出現大量的異常場景。而如果我們為了保護這些場景而加入大量的基本不會生效的if判斷中,那麼這些基本上不會起作用的if判斷,不但會嚴重的影響程式碼的可讀性和簡潔,還使讀者覺得這些異常場景是會經常發生的,同時對系統的效能也有一定的影響。 而assert可以有效的通過配置項,控制這段程式碼是否生效,這其實上是一個非常優雅的行為。 ps 寫完本段後,感覺非常有電視購物的感覺....其它的一些情況1、-ea和-da可以有效的指向到類和包路徑的某一級中,使得可以更靈活的控制assert的有效性。具體的使用如下:-ea java -ea 開啟所有使用者類別的assertion-da java -da 關閉所有使用者類別的assertion-ea: java -ea:MyClass1 開啟MyClass1的assertion-ea: java -ea:MyClass1 打開MyClass1的assertion-da: java -da: MyClass1 關閉MyClass1的assertion-ea: java -ea:pkg1 開啟pkg1套件的assertion -da: java-da:pkg1 關閉pkg1套件的assertion-ea:... java -ea :... 開啟預設包(無名包)的assertion-da:... java -da:... 關閉缺省包(無名包)的assertion-ea:... java -ea :pkg1... 開啟pkg1包和其子包的assertion🎜
-da:... java -da:pkg1... 關閉pkg1包和其子包的assertion
-esa java -esa 打開系統類的assertion
-dsa java -dsa 關閉系統類的assertion
2.assert的使用,是你知道這個事情在正常的情況下是絕對不會發生的,但是你也知道,OS、jvm中的事情是會偶然出現莫名其妙錯誤的,同時保不準某個調用你程式碼的人,跟你想的不一樣,錯誤的呼叫了你的程式碼。所以:
1)assert常被放置在使用者的核心處理程式碼中,翻閱java原始碼,就會發現原始碼中有大量的使用assert關鍵字。
2)assert處理的是那種正常情況下絕對不會出現的情況,所以在平常的業務流程中使用assert。
3)assert是不具有繼承性的
如果開啟父類別的assert,則執行到子類別的assert方法時,子類別是預設不開啟的。
反之如果開啟子類別的assert,運行到父類別的assert方法時,父類別的assert也是不開啟的。
參考文件
http://blog.sina.com.cn/s/blog_95feae0d0101comcg.html
http://lavasoft.blog.51cto.comcg.html
http://lavasoft.blog.51cto.comcg.html
http://lavasoft.blog.51cto.com/62575/4373535% zhihu.com/question/24461924