亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

JML起步--使用JML改進你的Java程序(2)

2019-11-18 13:17:39
字體:
來源:轉載
供稿:網友

  量詞(Quantification)(譯者注:這里量詞的意思與邏輯學上的量詞意思相近,而不是普通意義上理解的量詞。)
  
  在上面pop()方法的行為規范中,我們說它的返回值要等于peek()方法的返回值,不過我們并沒有看到關于peek()方法的規范。PRiorityQueue中peek()方法的行為規范請看下面的代碼:
  
  代碼段3 PriorityQueue 中peek()方法的行為規范
  
  /*@
  
    @ public normal_behavior
  
    @  requires ! isEmpty();
  
    @  ensures elementsInQueue.has(/result);
  
    @*/
  
  /*@ pure @*/ Object peek() throws NoSUChElementException;
  
  JML標記要求只有當隊列中至少含有一個元素的時候,才能調用peek()方法,同時他還要求方法的返回值必須在elementsInQueue之內,也就是說,這個返回值一定是這個隊列中的一個元素。
  
  注釋/*@ pure @*/ 表明peek()方法是一個純方法(pure method),純方法是指沒有副作用的方法。JML中只答應使用純方法進行斷言確認,所以我們把peek()聲明為純方法,這樣我們就可以在pop()方法的后置條件中使用peek()方法。大家肯定想知道,為什么JML只答應使用純方法進行斷言確認?問題是這樣的,假如JML答應使用非純方法進行斷言確認的話,我們稍不注重就會寫出有副作用的行為規范。比如說可能會有這么一種情況,開啟了斷言確認以后,我們的代碼正確無誤,可是假如禁止了斷言確認后,我們的代碼卻不能運行了,或運行出錯了。這樣當然不行!后面,我們還會進一步討論副作用的問題。
  
  關于繼續
  JML行為規范可以被子類(含子接口)或者是實現接口的類所繼續,這一點與J2SE1.4中斷言有所不同。JML要害字 also表示當前定義的行為規范與祖先類或被實現的接口中所定義的行為規范一起作用。因而,在 PriorityQueue接口定義的 peek()方法的行為規范同樣適用于 BinaryHeap類中的 peek()方法。這個就意味著,雖然在 BinaryHeap.peek()的行為規范中沒有明確定義, BinaryHeap.peek()的返回值也必須在 elementsInQueue當中。
  
  大頂堆和小頂堆(譯者注:大頂堆和小頂堆是數據結構里面的概念,分別表示堆排序方法的不同實現方式。堆排序是一種通過調整二叉樹進行排序的方法。)
  
  上面我們給peek()定義的行為規范明顯缺少了一塊,那就是我們根本沒有要求它返回的那個元素具有最大的優先級。顯然,JCCC的PriorityQueue接口既可以用于大頂堆,也可以用于小頂堆。大頂堆和小頂堆的表現是有些差別的,在小頂堆中優先級最高的元素值最小,而大頂堆中優先級最高的元素值最大。因為PriorityQueue并不知道自己被用來進行大頂堆排序還是小頂堆排序,所以指定返回哪個元素的規范必須在實現PriorityQueue接口的類中進行定義。
  
  在JCCC 中,類 BinaryHeap實現了PriorityQueue接口。BinaryHeap答應使用它的客戶代碼在構造函數中通過一個參數來指定排序方案,也就是通過參數來指定是通過大頂堆方式排序還是通過小頂堆方式排序。我們使用一個boolean模型變量isMinimumHeap來判定BinaryHeap的排序方式是大頂堆還是小頂堆。下面的例子是BinaryHeap使用isMinimumHeap給peek()方法定義的行為規范:
  
  代碼段4  BinaryHeap 類中peek()方法的行為規范
  
  /*@
  
    @ also
  
    @  public normal_behavior
  
    @   requires ! isEmpty();
  
    @   ensures
  
    @    (isMinimumHeap ==>
  
    @      (/forall Object obj;
  
    @         elementsInQueue.has(obj);
  
    @         compareObjects(/result, obj)
  
    @               <= 0)) &&
  
    @    ((! isMinimumHeap) ==>
  
    @      (/forall Object obj;
  
    @         elementsInQueue.has(obj);
  
    @         compareObjects(/result, obj)
  
    @               >= 0));
  
    @*/
  
  public Object peek() throws NoSuchElementException
  
  使用量詞
  上面代碼段4中的后置條件包含兩個部分,分別用于大頂堆和小頂堆的情況?!?=>”符號的意思是包含(譯者注:這個包含與邏輯學中包含的意思一致)。x ==> y 當且僅當y為真或x為假時取真值。對于小頂堆排序來說,適用下面所列的代碼:
  
  (/forall Object obj;
  
       elementsInQueue.has(obj);
  
       compareObjects(/result, obj) <= 0)
  
  上面的代碼中/forall是一個JML量詞。上面/forall表達式當所有的對象obj滿足elementsInQueue.has(obj)為真且compareObjects(/result, obj)返回一個非正數兩個條件時才為真。換言之,當使用compareObjects()進行比較時,peek()方法的返回值一定小于或等于elementsInQueue中每一個元素的值。其他的JML量詞還有/exists、/sum以及 /min等等。
  
  使用Comparator進行比較
  BinaryHeap類答應以兩種方法比較元素的大小。一種方法是要進行比較的元素自己實現Comparable接口,比較過程使用元素中定義的方法進行。另外一種方法是客戶類在構造BinaryHeap類的實例時向構造函數傳入一個Comparator對象,使用該Comparator對象進行比較。無論使用哪一種比較方式,我們都使用模型域comparator來表示比較大小所用的Comparator對象。 在peek()方法的后置條件中,compareObjects()方法使用客戶端選擇的比較方式來進行元素的比較。compareObjects()方法定義如下:
  
  代碼段5  compareObjects() 方法
  
  /*@
  
    @ public normal_behavior
  
    @  ensures
  
    @   (comparator == null) ==>
  
    @     (/result == ((Comparable) a).compareTo(b)) &&
  
    @   (comparator != null) ==>
  
    @     (/result == comparator.compare(a, b));
  
    @
  
    @ public pure model int compareObjects(Object a, Object b)
  
    @ {
  
    @ if (m_comparator == null)
  
    @   return ((Comparable) a).compareTo(b);
  
    @ else
  
    @   return m_comparator.compare(a, b);
  
    @ }
  
    @*/
  
  compareObjects方法的定義中使用了另外一個要害字model,它的意思是compareObjects方法是一個模型方法。模型方法是只能用在行為規范中的JML方法。模型方法定義在java的注釋中,所以常規的Java代碼不能使用。
  
  假如BinaryHeap類的客戶代碼指定了一個非凡的Comparator用來進行比較的話,m_comparator就指向那個Comparator,否則m_comparator的值就是null。compareObjects()方法檢查m_comparator的值,然后采用適當的方法進行元素間的比較。
  
  模型域如何取值
  在代碼段4中我們討論了peek()方法的后置條件。這個條件保證peek()方法的返回值的優先級大于或者等于模型域elementsInQueue中所有的元素的優先級。那么有一個問題,像elementsInQueue這樣的模型域如何取值?前置條件、后置條件和不變量都是沒有副作用的,所以不能使用它們來設置模型域的值。
  
  JML使用一個represents語句把模型域與具體的實現域關聯起來。比如下面的represents語句用來給模型域isMinimumHeap賦值:
  
  //@ private represents isMinimumHeap <- m_isMinHeap;
  
  這個語句的意思是模型域isMinimumHeap的值等于m_isMinHeap的值,其中,m_isMinHeap是BinaryHeap類中一個私有的布爾變量。 一旦需要用到isMinimumHeap的值,JML就會把m_isMinHeap的值賦給它。
  
  represents語句并沒有限制<-右邊必須是成員變量。比如說,下面是elementsInQueue的represents語句:
  
  代碼段6  elementsInQueue 的represents語句
  
  /*@ private represents elementsInQueue
  
    @     <- JMLObjectBag.convertFrom(
  
    @          Arrays.asList(m_elements)
  
    @           .subList(1, m_size + 1));
  
    @*/
  
  從這里我們可以看出,elementsInQueue的元素就是數組m_elements[]從第一個元素到第m_size個元素共m_size個元素構成的列表,其中數組m_elements[]是BinaryHeap的一個私有成員,用來存儲優先級隊列中的元素,m_size是m_elements[]中正在使用的元素的個數。類BinaryHeap沒有使用m_elements[0],這樣可以簡化對于索引的操作。JMLObjectBag.convertFrom()的作用是把一個List結構轉化為一個elementsInQueue所需要的JMLObjectBag結構。這樣一旦JML運行時進行斷言檢查的時候需要elementsInQueue的值,系統就會計算represents 語句<-符號右邊的代碼并進行求值。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久天天躁狠狠躁夜夜躁2014| 日韩中文视频免费在线观看| 国产在线日韩在线| 国产视频精品免费播放| 91精品综合久久久久久五月天| 97香蕉超级碰碰久久免费软件| 国产mv免费观看入口亚洲| 亚洲国产一区自拍| 午夜精品久久久久久久白皮肤| 久久久伊人欧美| 中文字幕国产精品| 国产精品av免费在线观看| 最好看的2019的中文字幕视频| 日韩中文在线视频| 青青在线视频一区二区三区| 欧美视频中文在线看| 亚洲精品国产精品国产自| 亚洲最大福利视频| 国产玖玖精品视频| 久久亚洲国产精品成人av秋霞| 亚洲免费视频一区二区| 欧美肥老太性生活视频| 欧美丰满少妇xxxxx做受| 国产精品福利在线观看| 色偷偷av一区二区三区| 久久91亚洲精品中文字幕| 成人免费网站在线| 亚洲欧美精品中文字幕在线| 日韩视频―中文字幕| 在线观看久久久久久| 尤物九九久久国产精品的特点| 韩国国内大量揄拍精品视频| 国产日韩精品电影| 亚洲国产高潮在线观看| 久久免费精品视频| 国产精品入口尤物| 亚洲精品资源在线| 久久久精品免费视频| 亚洲国产日韩一区| 韩国三级电影久久久久久| 成人福利网站在线观看| 欧美成在线视频| 91精品久久久久| 欧美日韩国产精品| 久久人人爽人人爽人人片av高请| 久久成人这里只有精品| 亚洲精品二三区| 亚洲va久久久噜噜噜| 亚洲人在线观看| 日韩免费观看视频| 久久综合九色九九| 亚洲成色777777在线观看影院| 成人黄色免费在线观看| 97激碰免费视频| 日韩三级影视基地| 久久91精品国产91久久跳| 国产精品久久久久久久久久久新郎| 欧美巨大黑人极品精男| 岛国av一区二区三区| 久久亚洲欧美日韩精品专区| 国产精品久久久久久影视| 欧美疯狂xxxx大交乱88av| 成人在线免费观看视视频| 亚洲**2019国产| 久久久久久久久久婷婷| 青青草一区二区| 欧洲精品久久久| xxx成人少妇69| 色噜噜国产精品视频一区二区| 久久精品在线播放| 日韩av在线网| 精品美女国产在线| 欧美成aaa人片免费看| 亚洲激情电影中文字幕| 成人久久久久久| 69**夜色精品国产69乱| 亚洲午夜性刺激影院| 日韩有码视频在线| 国产精品九九久久久久久久| 97在线看福利| 久久亚洲国产精品| 国产一区二区三区在线看| 国产一区二区三区日韩欧美| 欧美在线观看一区二区三区| 98午夜经典影视| 亚洲精品98久久久久久中文字幕| 国产国语videosex另类| 中文字幕精品av| 欧美又大又硬又粗bbbbb| 国产精品日韩久久久久| 日韩精品在线观看网站| 欧美裸体xxxx极品少妇| 欧美做受高潮电影o| 国产成人精品国内自产拍免费看| 久久综合色88| 日韩女优人人人人射在线视频| 国产精品久久一区| 日韩中文字幕在线视频播放| 欧美精品激情视频| 日韩性xxxx爱| 国产精品一区二区三区成人| 欧美国产日韩一区二区在线观看| 欧美尤物巨大精品爽| 自拍偷拍亚洲区| 日韩国产一区三区| 国产精品美女午夜av| 日韩免费黄色av| 国外成人在线直播| 668精品在线视频| 欧美电影在线观看完整版| www国产精品视频| 热久久视久久精品18亚洲精品| 国产欧亚日韩视频| 亚洲一区二区久久久| 久久91精品国产91久久跳| 一区二区欧美激情| 日韩免费观看网站| 国产成人精品免费视频| 亚洲精品v欧美精品v日韩精品| 欧洲成人免费视频| 一区二区亚洲欧洲国产日韩| 日韩成人av一区| 98精品在线视频| 91免费在线视频| 亚洲精品999| 不卡伊人av在线播放| 国产97人人超碰caoprom| 欧美午夜精品久久久久久久| 亚洲无限乱码一二三四麻| www.日本久久久久com.| 日韩高清av一区二区三区| 亚洲人成网7777777国产| 久久精品视频中文字幕| 日韩精品免费观看| 欧美成人午夜剧场免费观看| 国产精品亚洲美女av网站| 日韩在线中文字| 日韩经典中文字幕在线观看| 国产精品国产亚洲伊人久久| 91精品国产91久久久久久不卡| 91精品成人久久| 亚洲色无码播放| 亚洲精品在线不卡| 亚洲男子天堂网| 亚洲第一综合天堂另类专| 国产精品人成电影| 成人国产精品久久久| 日韩国产高清污视频在线观看| 色视频www在线播放国产成人| 在线日韩av观看| 国产精品揄拍一区二区| 欧洲精品久久久| 国产精品男人爽免费视频1| 国产午夜精品美女视频明星a级| 亚洲自拍欧美另类| 久久中文字幕国产| 91精品国产自产在线| 国产91网红主播在线观看| 亚洲欧洲在线观看| 亚洲免费中文字幕| 中文字幕精品一区久久久久| 国产热re99久久6国产精品| 国产精品久久97| 国产美女被下药99|