<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何在 Java 中使用斷言

          共 1099字,需瀏覽 3分鐘

           ·

          2021-01-17 15:02


          如何在 Java 中使用斷言

          什么是 Java 斷言?

          在 JDK 1.4之前,開發(fā)人員經常使用注釋來記錄關于程序正確性的假設。然而,注釋作為測試和調試假設的機制是無用的。編譯器忽略注釋,因此無法使用它們進行 bug 檢測。開發(fā)人員在更改代碼時也經常不更新注釋。

          在 JDK 1.4中,斷言被引入作為測試和調試代碼假設的新機制。實質上,斷言是在運行時執(zhí)行的可編譯實體,假設你已經為程序測試啟用了它們。可以通過編寫斷言來通知 bug 發(fā)生的地方,這樣可以大大減少調試失敗程序的時間。

          如何用 Java 編寫斷言

          編寫斷言的表達式:

          assert?BooleanExpr;

          如果 BooleanExpr 的計算結果為 true,則不會發(fā)生任何事情,并繼續(xù)執(zhí)行。但是,如果表達式計算結果為 false,那么將拋出 AssertionError

          舉個例子

          ????public?static?void?main(String[]?args)?{
          ????????int?a?=?10;
          ????????assert?a>100;//false
          ????}

          此斷言表明開發(fā)人員認為變量 a 包含一個大于100的值。但是,情況顯然不是這樣;

          assert 語句的執(zhí)行導致拋出 AssertionError

          運行后沒有反應??

          有的小伙伴發(fā)現(xiàn)自己的IDE并沒有拋出Error 這是因為沒有顯示開啟,啟用斷言開啟方法: vm options 加入 -ea

          此時我們運行項目 發(fā)現(xiàn)拋出了異常

          Exception?in?thread?"main"?java.lang.AssertionError
          ?at?Scratch.main(scratch_4.java:4)

          希望獲得更多信息?

          此時我們已經知道了斷言的基本用法 但是拋出Error后我們并不知道是什么問題導致的 還需要去翻看代碼找到報錯的地方, 如果我們希望獲得更多有用的信息 我們可以這樣修改Assert語句:

          assert?BooleanExpr?:?expr;

          expr 是任何可以返回值的表達式(包括方法調用)但是不能調用具有 void 返回類型的方法。一個有用的表達式是一個字符串,用它來描述失敗的原因

          舉個例子

          public?static?void?main(String[]?args)?{
          ????????int?a?=?10;
          ????????assert?a>100?:?"a?;?
          ????}

          運行:

          Exception?in?thread?"main"?java.lang.AssertionError:?a?100
          ?at?Scratch.main(scratch_4.java:5)

          無論哪個例子,在不使用-ea (啟用斷言)選項的情況下運行都不會產生輸出。當斷言未啟用時,它們不會執(zhí)行,盡管它們仍然存在于類文件中。

          前置條件和后置條件

          前置條件: 是在執(zhí)行某些代碼之前必須求值為 true 的條件

          后置條件: 是在執(zhí)行某些代碼后必須求值為 true 的條件

          前置條件

          前置條件檢查:

          import?java.io.FileInputStream;
          import?java.io.IOException;
          import?java.io.InputStream;

          class?PNG
          ????
          {
          ????????/**
          ?????????*??Create?a?PNG?instance,?read?specified?PNG?file,?and?decode
          ?????????*??it?into?suitable?structures.
          ?????????*
          ?????????*??@param?filespec?path?and?name?of?PNG?file?to?read
          ?????????*
          ?????????*??@throws?NullPointerException?when?filespec?is
          ?????????*??????????null
          ?????????*/

          ????????PNG(String?filespec)?throws?IOException
          ????????{
          ????????????//在非私有構造方法中?使用前置條件
          ????????????if?(filespec?==?null)
          ????????????????throw?new?NullPointerException("filespec?is?null");
          ????????????try?(FileInputStream?fis?=?new?FileInputStream(filespec))
          ????????????{
          ????????????????readHeader(fis);
          ????????????}
          ????????}

          ????????private?void?readHeader(InputStream?is)?throws?IOException
          ????????
          {??
          ????????????????//在私有方法中使用前置條件檢查
          ????????????assert?is?!=?null?:?"null?passed?to?is";
          ????????}
          ????}

          ????class?Scratch
          ????
          {
          ????????public?static?void?main(String[]?args)?throws?IOException
          ????????
          {
          ????????????PNG?png?=?new?PNG((args.length?==?0)???null?:?args[0]);
          ????????}
          ????}

          后置條件

          后置條件檢查:

          public?class?AssertDemo
          {
          ???public?static?void?main(String[]?args)
          ???
          {
          ??????int[]?array?=?{?20,?91,?-6,?16,?0,?7,?51,?42,?3,?1?};
          ??????sort(array);
          ??????for?(int?element:?array)
          ?????????System.out.printf("%d?",?element);
          ??????System.out.println();
          ???}

          ???private?static?boolean?isSorted(int[]?x)
          ???
          {
          ??????for?(int?i?=?0;?i?1;?i++)
          ?????????if?(x[i]?>?x[i?+?1])
          ????????????return?false;
          ??????return?true;
          ???}

          ???private?static?void?sort(int[]?x)
          ???
          {
          ??????int?j,?a;
          ??????//?For?all?integer?values?except?the?leftmost?value?...
          ??????for?(int?i?=?1;?i???????{
          ?????????//?Get?integer?value?a.
          ?????????a?=?x[i];
          ?????????//?Get?index?of?a.?This?is?the?initial?insert?position,?which?is
          ?????????//?used?if?a?is?larger?than?all?values?in?the?sorted?section.
          ?????????j?=?i;
          ?????????//?While?values?exist?to?the?left?of?a's?insert?position?and?the
          ?????????//?value?immediately?to?the?left?of?that?insert?position?is
          ?????????//?numerically?greater?than?a's?value?...
          ?????????while?(j?>?0?&&?x[j?-?1]?>?a)
          ?????????{
          ????????????//?Shift?left?value?--?x[j?-?1]?--?one?position?to?its?right?--
          ????????????//?x[j].
          ????????????x[j]?=?x[j?-?1];
          ????????????//?Update?insert?position?to?shifted?value's?original?position
          ????????????//?(one?position?to?the?left).
          ????????????j--;
          ?????????}
          ?????????//?Insert?a?at?insert?position?(which?is?either?the?initial?insert
          ?????????//?position?or?the?final?insert?position),?where?a?is?greater?than
          ?????????//?or?equal?to?all?values?to?its?left.
          ?????????x[j]?=?a;
          ??????}
          ??????//在 sort ()返回給它的調用者之前,我使用 assert 檢查 x 被排序的后置條件。
          ??????assert?isSorted(x):?"array?not?sorted";
          ???}
          }

          陷阱

          assert關鍵字用法簡單,但是使用assert往往會讓你陷入越來越深的陷阱中。應避免使用。筆者經過研究,總結了以下原因:

          1、 assert關鍵字需要在運行時候顯式開啟才能生效,否則你的斷言就沒有任何意義。而現(xiàn)在主流的Java IDE工具默認都沒有開啟-ea斷言檢查功能。這就意味著你如果使用IDE工具編碼,調試運行時候會有一定的麻煩。并且,對于Java Web應用,程序代碼都是部署在容器里面,你沒法直接去控制程序的運行,如果一定要開啟-ea的開關,則需要更改Web容器的運行配置參數(shù)。這對程序的移 植和部署都帶來很大的不便。

          2、用assert代替if是陷阱之二。assert的判斷和if語句差不多,但兩者的作用有著本質的區(qū)別:assert關鍵字本意上是為測試 調試程序時使用的,但如果不小心用assert來控制了程序的業(yè)務流程,那在測試調試結束后去掉assert關鍵字就意味著修改了程序的正常的邏輯。

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

          總結

          assert既然是為了調試測試程序用,不在正式生產環(huán)境下用,那應該考慮更好的測試JUint來代替其做用,JUint相對assert關鍵的所提供的功能是有過之而無不及。當然完全可以通過IDE debug來進行調試測試

          因此,應當避免在Java中使用assert關鍵字,除非哪一天Java默認支持開啟-ea的開關,這時候可以考慮。對比一下,assert能給你帶來多少好處,多少麻煩,這是我們選擇是否使用的的原則,讀者可以自行取舍.

          完 小伙伴記得點贊 關注!!

          今天我們主要分析Thread Dump


          學習單例模式引發(fā)的思考


          JVM生成的這3種文件,你都見過嗎?


          一文搞懂什么是事務



          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久久久伊人 | 艳舞乱伦小说 | AA片在线观看视频 | 台湾在线无码视频 | 亚洲精品午夜成人片DY888 |