posts - 8,  comments - 6,  trackbacks - 0

          1.6  要決斷:使用Java斷言 

          Java5+

          “編程人員總是正確的—— 是編譯器和解釋器造成的錯(cuò)誤。”我確信你認(rèn)同這種說法。作為編程人員,經(jīng)常要對變量的值做出假設(shè)并且基于此編寫代碼。盡管非常不愿意承認(rèn)可能在設(shè)計(jì)或?qū)崿F(xiàn)上有錯(cuò)誤,但有時(shí)變量和參數(shù)卻沒有獲得期望的值。

          當(dāng)設(shè)計(jì)和編寫代碼時(shí),只有在最初的假設(shè)仍然成立的情況下代碼才能正確運(yùn)行。如果沒有任何有關(guān)這些假設(shè)的聲明,那么閱讀代碼的任何人(甚至你自己)都不清楚它們的含義是什么。從而導(dǎo)致今后的改動(dòng)可能會(huì)違反這些假設(shè)并引入難以查找的錯(cuò)誤。通常,在注釋中說明假設(shè)能使以后修改代碼的人避免出錯(cuò)。

          使用注釋來說明假設(shè)是一個(gè)好的開始。但是當(dāng)出現(xiàn)違反假設(shè)的情況時(shí),程序有時(shí)會(huì)繼續(xù)運(yùn)行就像未出現(xiàn)任何問題一樣。一些情況下,開發(fā)人員能夠馬上看到結(jié)果,并且可以糾正出現(xiàn)的問題。但在另一些情況下,存在一個(gè)潛伏的錯(cuò)誤時(shí),可能會(huì)對應(yīng)用程序的其他部分造成負(fù)面影響,對于分布式系統(tǒng)而言,則可能會(huì)對完全不同的另一個(gè)應(yīng)用程序造成負(fù)面影響!跟蹤這樣的問題非常困難。

          Java 1.4在語言中添加了斷言特性來簡化測試和調(diào)試,加強(qiáng)文檔編制并提高基于Java的可維護(hù)性。可以使用一個(gè)布爾表達(dá)式來創(chuàng)建一個(gè)斷言,以便測試有關(guān)系統(tǒng)的當(dāng)前狀態(tài)所假定的某些情況。如果斷言失敗,運(yùn)行庫會(huì)拋出一個(gè)AssertionError。下面給出一個(gè)很簡單的斷言:

          String name = "Brian";
          assert name != null;

          這里,可以確定在給name分配了值“Brian”后它的值將不會(huì)為空。如果它的值為空,則出現(xiàn)了某種嚴(yán)重的錯(cuò)誤!此斷言是當(dāng)時(shí)在程序中對變量的值所做的假定的聲明。為如此簡單的例子做這種聲明看似可笑和多余。但是,當(dāng)多個(gè)方法會(huì)影響一個(gè)對象的狀態(tài)時(shí),這種方法是有效的。在下面的示例中,示例了這樣一個(gè)斷言,即在向新員工分配任何任務(wù)之前必須已經(jīng)指派了一名管理人員。

          Employee worker =
          new Employee("John", "Smith", 100000, "Developer");
          assignOffice(worker);
          setUpVoiceMail(worker);
          moreAdministrivia(worker);
          assert worker.getSupervisor() != null : "Supervisor cannot be null";
          assignTasks(worker);

          通常,在對某個(gè)對象執(zhí)行關(guān)鍵操作時(shí)會(huì)需要對它創(chuàng)建斷言。這有助于增強(qiáng)代碼的健壯性,比如如果在程序中出現(xiàn)了某種錯(cuò)誤,可以更方便地調(diào)試程序。這樣做要比程序在某處執(zhí)行失敗造成不良后果來發(fā)現(xiàn)錯(cuò)誤要好得多。當(dāng)知道程序失敗是由于它違反了假設(shè)而引起的時(shí)候,跟蹤失敗的原因要簡單得多。在這個(gè)代碼樣例中,使用了assert選項(xiàng)來返回更有用的信息。沒有此選項(xiàng)時(shí),除了行號之外將無法得到有關(guān)斷言的標(biāo)識信息。

          在某些版本的編譯器上,當(dāng)編譯源代碼時(shí)需要使用一個(gè)命令選項(xiàng)來設(shè)置編譯器的源兼容性模式(取決于編譯器的版本,如1.4或1.5)。

          javac -source 1.5 MyClass.java

          現(xiàn)在強(qiáng)制斷言失敗并觀察會(huì)出現(xiàn)什么情況:

          public class AssertBad {
          public static void main(String[] args) {
          int total = 20;
          int itemCount = 0;
          assert itemCount > 0;
          int average = total / itemCount;
          }
          }


          默認(rèn)情況下,運(yùn)行時(shí)環(huán)境不支持?jǐn)嘌?,必須使用ea(允許斷言)命令選項(xiàng)來啟動(dòng)JRE。上面的代碼會(huì)引起以下的結(jié)果:

          C:\projects\wcj1> java -ea AssertBad
          Exception in thread "main" java.lang.AssertionError
          at AssertBad.main(AssertBad.java:12)


          要記住斷言是用來對那些不應(yīng)該出現(xiàn)的情況進(jìn)行實(shí)際的“健全性檢查”,因此不應(yīng)該使用它們來替代常規(guī)的錯(cuò)誤檢查。

          警告:
          不要讓斷言語句更改代碼中的狀態(tài)/值。否則當(dāng)最終關(guān)閉斷言時(shí),代碼的行為方式將不同于啟用斷言時(shí)代碼的行為。例如,不要?jiǎng)?chuàng)建如下的斷言:

          assert (++i > 10); // BAD: i changes only with assertions enabled!

          通常,在整個(gè)開發(fā)階段都會(huì)啟用斷言。一旦完全測試了系統(tǒng)并將它移送到產(chǎn)品環(huán)境時(shí),則希望禁用斷言,因?yàn)檫@樣做會(huì)略微改善性能。但是不要改動(dòng)代碼來完成此操作,并且也不要?jiǎng)h除斷言。不管怎樣,為了編制文檔的目的,斷言也應(yīng)保留在代碼中。這樣,當(dāng)以后更改代碼時(shí),會(huì)提醒程序員要保持所有假設(shè)都是有效的,并且這也是可測試的。


          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          主站蜘蛛池模板: 青川县| 襄汾县| 广昌县| 苍溪县| 大石桥市| 卓尼县| 金门县| 日喀则市| 颍上县| 南昌县| 旺苍县| 鹤庆县| 精河县| 邯郸县| 房山区| 固阳县| 营口市| 伊金霍洛旗| 兴安县| 望谟县| 康乐县| 卢氏县| 乾安县| 和硕县| 灌阳县| 宁化县| 油尖旺区| 澄迈县| 常山县| 太保市| 黄梅县| 通渭县| 桐柏县| 仁布县| 阿鲁科尔沁旗| 女性| 浙江省| 临澧县| 玛多县| 淳安县| 临沂市|