posts - 73,  comments - 55,  trackbacks - 0
          斷言概述

          編寫代碼時(shí),我們總是會(huì)做出一些假設(shè),斷言就是用于在代碼中捕捉這些假設(shè)
          可以將斷言看作是異常處理的一種高級(jí)形式

          斷言表示為一些布爾表達(dá)式,程序員相信在程序中的某個(gè)特定點(diǎn)該表達(dá)式值為真

          可以在任何時(shí)候啟用和禁用斷言驗(yàn)證,因此可以在測試時(shí)啟用斷言而在部署時(shí)禁用斷言。同樣,程序投入運(yùn)行后,最終用戶在遇到問題時(shí)可以重新起用斷言。

          使用斷言可以創(chuàng)建更穩(wěn)定,品質(zhì)更好且易于除錯(cuò)的代碼

          當(dāng)需要在一個(gè)值為FALSE時(shí)中斷當(dāng)前操作的話,可以使用斷言

          單元測試必須使用斷言(Junit/JunitX

          除了類型檢查和單元測試外,斷言還提供了一種確定個(gè)種特性是否在程序中得到維護(hù)的極好的方法

          使用斷言使我們向按契約式設(shè)計(jì)更近了一步



          常見的斷言特性


          前置條件斷言:代碼執(zhí)行之前必須具備的特性

          后置條件斷言:代碼執(zhí)行之后必須具備的特性

          前后不變斷言:代碼執(zhí)行前后不能變化的特性



          斷言使用方式


          斷言可以有兩種形式

          1.assert Expression1
          2.assert Expression1:Expression2
          其中Expression1應(yīng)該總是一個(gè)布爾值,Expression2是斷言失敗時(shí)輸出的失敗消息的字符串。如果Expression1為假,則拋出一個(gè) AssertionError,這是一個(gè)錯(cuò)誤,而不是一個(gè)異常,也就是說是一個(gè)不可控制異常(unchecked Exception),AssertionError由于是錯(cuò)誤,所以可以不捕獲,但不推薦這樣做,因?yàn)槟菢訒?huì)使你的系統(tǒng)進(jìn)入不穩(wěn)定狀態(tài)。



          起用斷言


          斷言在默認(rèn)情況下是關(guān)閉的,要在編譯時(shí)啟用斷言,需要使用source1.4標(biāo)記javac source1.4 Test.java ,在運(yùn)行時(shí)啟用斷言需要使用 -ea參數(shù)。要在系統(tǒng)類中啟用和禁用斷言可以使用 -esa -dsa參數(shù)。


          例如:

          public >  public AssertExampleOne(){}
            public static void main(String args[]){
              int x=10;
              System.out.println("Testing Assertion that x==100");
              assert x=100;"Out assertion failed!";
              System.out.println("Test passed!");
            }
          }

          如果編譯時(shí)未加 -source1.4,則編譯通不過

          在執(zhí)行時(shí)未加 -ea 時(shí)輸出為

          Testing Assertion that x==100
          Test passed
          jre
          忽略了斷言的就代碼,而使用了該參數(shù)就會(huì)輸出為

          Testing Assertion that x==100
          Exception in thread "main" java.lang.AssertionError: Out assertion failed!
          at AssertExampleOne.main(AssertExampleOne.java:6)


          斷言的副作用


          由于程序員的問題,斷言的使用可能會(huì)帶來副作用,例如:

          boolean isEnable=false;
          //...
          assert isEnable=true;
          這個(gè)斷言的副作用是因?yàn)樗薷牧顺绦蛑凶兞康闹挡⑶椅磼伋鲥e(cuò)誤,這樣的錯(cuò)誤如果不細(xì)心的檢查是很難發(fā)現(xiàn)的。但是同時(shí)我們可以根據(jù)以上的副作用得到一個(gè)有用的特性,根據(jù)它來測試斷言是否打開。


          public >
            public static void main(String args[]){
              boolean isEnable=false;
              //...
              assert isEnable=true;
              if(isEnable==false){
                throw new RuntimeException("Assertion shoule be enable!");
              }
            }
          }


          何時(shí)需要使用斷言


          1.
          可以在預(yù)計(jì)正常情況下程序不會(huì)到達(dá)的地方放置斷言
          assert false
          2.
          斷言可以用于檢查傳遞給私有方法的參數(shù)。(對(duì)于公有方法,因?yàn)槭翘峁┙o外部的接口,所以必須在方法中有相應(yīng)的參數(shù)檢驗(yàn)才能保證代碼的健壯性)

          3.
          使用斷言測試方法執(zhí)行的前置條件和后置條件

          4.
          使用斷言檢查類的不變狀態(tài),確保任何情況下,某個(gè)變量的狀態(tài)必須滿足。(如age屬性應(yīng)大于0小于某個(gè)合適值)



          什么地方不要使用斷言


          斷言語句不是永遠(yuǎn)會(huì)執(zhí)行,可以屏蔽也可以啟用

          因此:

          1.
          不要使用斷言作為公共方法的參數(shù)檢查,公共方法的參數(shù)永遠(yuǎn)都要執(zhí)行

          2.
          斷言語句不可以有任何邊界效應(yīng),不要使用斷言語句去修改變量和改變方法的返回值

          下邊是介紹斷言的用法
          :

          assert是在J2SE1.4中引入的新特性,assertion就是在代碼中包括的布爾型狀態(tài),程序員認(rèn)為這個(gè)狀態(tài)是true。一般來說assert在開發(fā)的時(shí)候是檢查程序的安全性的,在發(fā)布的時(shí)候通常都不使用assert。在1.4中添加了assert關(guān)鍵字和java.lang.AssertError類的支持。
          首先,我們有必要從一個(gè)例子說起
          assert

          public >  public static void main(String[] args) {
              AssertTest at = new AssertTest();
              at.assertMe(true);
              at.assertMe(false);
            } 
            private void assertMe(boolean boo) {
              assert boo?true:false;
              System.out.println("true condition");
            }
          }
          程序中包含了assert的話,你要用javac -source 1.4 xxx.java來編譯,否則編譯器會(huì)報(bào)錯(cuò)的。要想讓assert得部分運(yùn)行的話,要使用java -ea xxx來運(yùn)行,否則包含assert得行會(huì)被忽略。下面我們運(yùn)行

          javac -source 1.4 AssertTest.java
          java -ea AssertTest
          看看結(jié)果的輸出是:


          true condition
          Exception in thread "main" java.lang.AssertionError
          at AssertTest.assertMe(AssertTest.java:13)
          at AssertTest.main(AssertTest.java:7)

          當(dāng)我們運(yùn)行at.assertMe(true)得時(shí)候,由于assert boo?true:false相當(dāng)于 assert true;因此沒有任何問題,程序往下執(zhí)行打印出true condition,但是執(zhí)行at.assertMe(false)的時(shí)候相當(dāng)于assert false,這個(gè)時(shí)候解釋器就會(huì)拋出AssertionError了,程序就終止了。大家必須清楚AssertionError是繼承自Error得,因此你可以不再程序中catch它的,當(dāng)然你也可以在程序中catch它然后程序可以繼續(xù)執(zhí)行。例如:

          public >  public static void main(String[] args) {
              AssertTest at = new AssertTest();
              try {
                at.assertMe(true);
                at.assertMe(false);
              } catch(AssertionError ae) {
                System.out.println("AsseriontError catched");
              }
              System.out.println("go on");
            }
            private void assertMe(boolean boo) {
              assert boo?true:false;
              System.out.println("true condition");
            }
          }

          assert
          還有另外一種表達(dá)的方式,就是assert exp1:exp2;其中exp1是個(gè)boolean返回值得表達(dá)式,而exp2可以是原始的數(shù)據(jù)類型或者對(duì)象都可以例如:

          boolean boo = true;
          String str = null;
          assert boo = false
          str="error";

          我們剛開始講得assert exp1得形式,當(dāng)exp1false得時(shí)候,AssertionError得默認(rèn)構(gòu)造器會(huì)被調(diào)用,但是assert exp1:exp2這樣的形式,當(dāng)exp1true的時(shí)候后面exp2被或略,如果false的話,后面的表達(dá)式的結(jié)果會(huì)被計(jì)算出來并作為AssertionError得構(gòu)造器參數(shù)。看下面的例子:

          public >  public static void main(String[] args) {
              AssertTest at = new AssertTest();
              at.assertMe(true);
              at.assertMe(false);
            }
            private void assertMe(boolean boo) {
              String s = null;
              assert boo?true:false:s = "hello world";
              System.out.println("true condition");
            }
          }


          運(yùn)行的時(shí)候會(huì)得到這樣的結(jié)果:

          true condition
          Exception in thread "main" java.lang.AssertionError: hello world
          at AssertTest.assertMe(AssertTest.java:14)
          at AssertTest.main(AssertTest.java:7)

          Assert
          最好不要濫用,原因是assert并不一定都是enable的,下面兩種情況就不應(yīng)該用
          assert

          不要在public的方法里面檢查參數(shù)是不是為null之類的操作,
          例如

          public int get(String s) {
            assert s != null;
          }
          如果需要檢查也最好通過if s = null 拋出NullPointerException來檢查


          不要用
          assert來檢查方法操作的返回值來判斷方法操作的結(jié)果,
          例如

          assert list.removeAll();

          這樣看起來好像沒有問題
          但是想想如果assert disable呢,那樣他就不會(huì)被執(zhí)行了所以removeAll()操作就沒有被執(zhí)行可以這樣代替

          boolean boo = list.removeAl();
          assert boo;
          posted on 2007-10-12 13:16 保爾任 閱讀(940) 評(píng)論(0)  編輯  收藏 所屬分類: J2SE

          <2007年10月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 隆尧县| 昌平区| 开封县| 孝义市| 淮滨县| 涟源市| 海口市| 安化县| 崇义县| 界首市| 巴楚县| 昭平县| 肇源县| 东台市| 富川| 临朐县| 原平市| 桐梓县| 通榆县| 合江县| 靖州| 庐江县| 昌邑市| 左贡县| 库尔勒市| 舒城县| 龙南县| 郧西县| 凭祥市| 长宁县| 区。| 曲靖市| 田阳县| 济阳县| 依安县| 达尔| 新津县| 蚌埠市| 克什克腾旗| 西丰县| 海原县|