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

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

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

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

  java建模語言(Java Modeling Language,JML)是一種進行具體設計的符號語言,他鼓勵你用一種全新的方式來看待Java的類和方法。本教程中,Java程序設計資深顧問Joe Verzulli 將會給大家介紹這一新的工具以及如何使用這個工具。
  
  面向對象的分析和設計(OOAD)的一個重要原則就是過程性的思考應該盡可能地推遲,不過遵循這個原則的大多數人也不過是把這個原則適用到方法實現這個級別上。一旦設計好了類和接口,下面的事情自然就是實現其中定義的方法了。對呀,我們還能做什么呢?還有什么其它方法可以使用嗎?究竟,用Java進行程序設計和用其他語言進行程序設計一樣,我們都要一步一步地實現每一個方法。
  
  標記本身只是表示如何做一個事情(how to do something),根本不管我們希望做什么。假如我們在做一個事情之前就能夠知道我們能夠達到什么樣的結果是非常好的,不過Java語言并沒有給我們提供一個可以顯示地把這些信息插入到我們程序代碼的方法。
  
  Java建模語言(Java Modeling Language,JML)在Java代碼中增加了一些符號,這些符號用來標識一個方法是干什么的,卻并不關心它的實現。假如使用JML的話,我們就能夠描述一個方法的預期的功能而不管他如何實現。通過這種方式,JML把過程性的思考延遲到方法設計中,從而擴展了面向對象設計的這個原則。
  
  JML引入了大量用于描述行為的結構,比如有模型域、量詞、斷言可視范圍、預處理、后處理、條件繼續以及正常行為(與異常行為相對)規范等等。這些結構使得JML非常強大,不過你并不必要理解或者使用上面所述的所有方面,也不需要一次使用所有的這些方面。你可以一點一點的學習,從非常簡單的開始。
  
  這篇文章中采用循序漸進的方式來介紹JML。我們要先了解一下使用JML的各種好處,非凡是對開發和編譯過程的影響。然后,我們要討論一下JML的一些結構,比如前置條件、后置條件、模型域、量詞、副作用以及異常行為等等。同時,在討論這些結構的同時,我們會給出一些例程來給你一個直觀的感覺。這樣經過本文的學習,你將可以對JML是如何工作的有一個概念性的理解,從而能夠在你自己的項目中應用JML。
  
  JML概覽
  使用JML來聲明性地描述一個方法或類的預期行為可以顯著提高整體的開發進程。把建模標記加入到你的Java程序代碼中有以下好處:
  
  能夠更為精確地描述這些代碼是做什么的
  能夠高效地發現和修正程序中的bug
  可以在應用程序升級時降低引入bug的機會
  可以提早發現客戶代碼對類的錯誤使用
  可以提供與應用程序代碼完全一致的JML格式的文檔
  JML標記總是在Java注釋的內部,所以對正常編譯的代碼沒有任何影響。假如你想比較一下普通的類和使用了JML的類有什么差別的話,你可以使用一個開源的JML編譯器(請參考 如下地址)。用JML編譯器編譯的代碼假如沒有實現JML規范所要求的事項,運行時就會拋出一個JML異常。這個特性不僅可以幫助我們捕捉代碼中的bug,而且可以確保JML形式的文檔可以與程序代碼高度一致。
  
  文章下面的部分,我將使用開放源代碼的Jakarta Commons Collection Component (JCCC)項目中的PRiorityQueue接口和BinaryHeap 類來演示JML的各種性質。在這里你可以找到使用了JML標記完整的這個兩個文件。
  
  要求和責任
  本文中使用的代碼(請參考 如下地址)包括開源項目JCCC中的PriorityQueue 接口。接口嘛,自然是聲明了一些方法的簽名,包括方法的參數類型、返回值的類型,并不涉及方法的實現。一般情況下或者只是按照Java語法要求的話,實現接口的類只要實現了接口中定義的各個方法即可,不論實現的方式是多么地離奇古怪。我們并不想這樣,我們希望能夠確定一個行為規范,所有實現這個接口的類都用我們指定的方式來實現這個接口中定義的方法。通過使用JML我們可以做到這一點。
  
  考慮一下PriorityQueue接口的pop()方法,對于優先級隊列來說,pop()方法應該有什么樣的功能要求?最起碼應該有三個:第一,假如要調用pop()方法,隊列中至少要有一個元素;第二,該方法應該返回隊列中優先級最高的那個元素;第三,該方法應該從隊列中刪除返回的那個元素。
  
  下面代碼段顯示了表示滿足第一個要求的JML標記:
  
  代碼段1 pop()方法功能規范的JML標記
  
  /*@
  
    @  public normal_behavior
  
    @   requires ! isEmpty();
  
    @*/
  
  Object pop() throws NoSUChElementException;
  
  前面已經提到,JML標記是寫在Java代碼的注釋中的。包含JML標記的多行注釋以/*@ 開頭,JML忽略任何以@開頭的空行。假如是單行的話,你也可以使用//@這種標記。
  
  這里JML注釋中public要害字與Java中的public意思是一樣的,它表示程序中其他所有的類都要遵循這個JML要求。Public要求只能應用在public方法和public成員變量上。JML同樣有private-、 protected-、 以及 package-級別的作用域。同樣,這些作用域的規則與Java語言中作用域的規則非常相似。
  
  這里normal_behavior要害字的意思是,這個JML要求表示這是一種正常情況,運行時不會拋出異常。后面,我們會描述異常行為是怎么被界定的。
  
  前置條件和后置條件
  JML要害字requires用來表示前置條件,前置條件表示調用一個方法前必須滿足的一些要求。上面代碼段中包含一個前置條件,它要求調用pop()方法的前提就是isEmpty()方法返回false,也就是說要求這個隊列至少含有一個元素。
  
  一個方法的后置條件規范表示一個方法的責任,也就是說當這個方法返回時,它必須滿足這個后置條件的要求。在我們上面的例子中,pop()方法應該返回隊列中優先級最高的元素。我們希望指定一個后置條件要求JML在運行時檢查是否滿足這個事實。要做到這一點,我們必須跟蹤所有添加到這個優先級隊列中的元素,這樣我們就可以判定pop()方法應該返回哪一個元素。怎么做呢?你可能會考慮在PriorityQueue接口中加入一個成員變量來存儲隊列中元素的值,不過這樣做有兩個問題:
  
  PriorityQueue是一個接口,它可能有各種不同具體的實現方式,比如說binary heap、Fibonacci heap或者calendar queue等等,它要與它的各種實現一致,況且JML標記不應該涉及到任何具體的實現細節。
  作為一個接口,PriorityQueue只能擁有靜態成員變量。
  為了處理這種情況,JML引入了一個叫做模型域(model fields)的概念。
  
  模型域
  模型域類似于成員變量,它只能被應用到行為規范中。這是一個PriorityQueue中聲明模型域的例子:
  
  //@ public model instance JMLObjectBag elementsInQueue;
  
  這個聲明的意思是說這里有一個叫做elementsInQueue的模型域,它的類型是JMLObjectBag (這個數據類型是在JML中定義的)。instance要害字表示雖然這個域是定義在接口中,可是任何實現這個接口的類都擁有一個單獨的、非靜態的elementsInQueue域。與其他JML標記一樣,這個聲明也是出現在注釋中的,所以常規的Java代碼是不能使用這個elementsInQueue變量的。在程序運行的時候,是沒有任何對象擁有一個叫做elementsInQueue的成員變量的。
  
  行為規范與實現
  使用一個包來存儲隊列中的元素,然后檢查每一個元素找出優先級最高的那一個會讓人覺得效率不高。不過這只是行為規范的一部分,而不會涉及到實現。行為規范的作用在于描述 PriorityQueue的行為接口,也就是說規定了使用 PriorityQueue的客戶代碼所能依靠的外部行為。
  
  PriorityQueue接口的各個具體實現只要可以滿足這個行為規范的要求,就可以使用任何更為高效的方法。比如說,JCCC有一個實現這個接口的 BinaryHeap類,它的實現方式就是使用一個存儲在數組中的 binary heap 。
  
  不過雖然用JML定義行為規范的時候不需要考慮執行效率,程序運行時JML斷言檢查卻是很重要的。所以開啟斷言檢查時程序的運行可能會有性能的壓力。
  
  elementsInQueue 存儲添加到優先級隊列的元素的值,下面的代碼段顯示pop()方法如何使用elementsInQueue:
  
  代碼段2 在pop()的后置條件中使用模型域
  
  /*@
  
    @ public normal_behavior
  
    @  requires ! isEmpty();
  
    @  ensures
  
    @   elementsInQueue.equals(((JMLObjectBag)
  
    @     /old(elementsInQueue))
  
    @            .remove(/result)) &&
  
    @   /result.equals(/old(peek()));
  
    @*/
  
  Object pop() throws NoSuchElementException;
  
  ensures要害字表示后面跟著的是pop()方法返回時必須滿足的后置條件。/result是一個JML要害字,它等于pop()方法的返回值。/old()是一個JML函數,它返回pop()方法調用之前參數的值。
  
  這個ensures語句包含了兩個后置條件。第一,pop()方法返回的那個元素必須要從elementsInQueue刪除。第二,這個返回值要與peek()方法返回的值一致。
  
  類級別的不變量
  我們現在已經看到JML能夠讓我們規定方法的前置條件和后置條件,它同樣也答應我們指定類級別的不變量。類級別的不變量指的是進入和退出一個類中每個方法都必須滿足的條件。比方說吧,//@ public instance invariant elementsInQueue != null; 就是PriorityQueue的一個不變量,它的意思是任何實現PriorityQueue的類一旦被實例化,elementsInQueue的值就不能是null。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产丝袜一区二区三区免费视频| 久久精品2019中文字幕| 久久影院中文字幕| 国产精品免费网站| 欧美一区亚洲一区| 动漫精品一区二区| 国产成人精品视频在线| 欧美老女人性生活| 爱福利视频一区| 亚洲变态欧美另类捆绑| 久久综合伊人77777蜜臀| 中文欧美日本在线资源| 久久手机精品视频| 免费97视频在线精品国自产拍| 91av在线播放| 亚洲精品久久久一区二区三区| 亚洲欧美一区二区精品久久久| 中文字幕欧美日韩精品| 日韩精品亚洲视频| 久久精品国产精品亚洲| 国产精品久久久av久久久| 国产999精品视频| www.日韩不卡电影av| 亚洲综合大片69999| 欧美黄色www| 日韩在线视频观看| 亚洲情综合五月天| 亚洲男人天天操| 亚洲国产高潮在线观看| 国内精品视频久久| 亚洲第一精品夜夜躁人人爽| 日韩欧美中文在线| 国产一区二区三区在线免费观看| 欧美日韩亚洲国产一区| 久久久久久久久久国产| 国内揄拍国内精品| 成人444kkkk在线观看| 久久精品成人欧美大片古装| 中国人与牲禽动交精品| 亚洲精品第一页| 久久久久久久激情视频| 国产亚洲成av人片在线观看桃| 国产精品青青在线观看爽香蕉| 国产精品第100页| 91午夜理伦私人影院| 日韩欧美在线第一页| 中国日韩欧美久久久久久久久| 亚洲一区亚洲二区| 一本色道久久综合亚洲精品小说| 国模吧一区二区| 91精品啪aⅴ在线观看国产| 668精品在线视频| 国产+成+人+亚洲欧洲| 国产欧美久久一区二区| 中文字幕亚洲一区| 久热精品视频在线| 精品一区精品二区| 国产精品日韩欧美综合| 国产极品精品在线观看| 日韩电影免费在线观看中文字幕| 久久影院资源网| 亚洲欧美精品一区二区| 日本精品久久中文字幕佐佐木| 久久人人97超碰精品888| 欧美精品www| 92福利视频午夜1000合集在线观看| 久久久久国色av免费观看性色| 人九九综合九九宗合| 亚洲人精品午夜在线观看| 日韩欧美中文字幕在线播放| 在线观看免费高清视频97| 韩国三级日本三级少妇99| 亚洲国产精品va在线| 欧美孕妇与黑人孕交| 国模私拍一区二区三区| 久久这里有精品| 亚洲视频在线观看免费| 亚洲国产成人爱av在线播放| 中文字幕亚洲一区在线观看| 国产91露脸中文字幕在线| 91免费人成网站在线观看18| 国产精品亚洲美女av网站| 91精品国产免费久久久久久| 中文字幕国内精品| 国产精品v片在线观看不卡| 精品久久久免费| 91免费精品国偷自产在线| 在线视频欧美日韩| 国产精品美女网站| 中文字幕亚洲综合久久| 欧美性资源免费| 日韩在线视频免费观看高清中文| 少妇高潮久久77777| 成人精品aaaa网站| 亚洲欧美日韩成人| 欧美日韩国产丝袜另类| 日韩中文字幕视频在线观看| 日韩中文在线中文网在线观看| 国产一区二区三区视频| 中文字幕亚洲无线码在线一区| 一区二区成人精品| 国产69精品久久久| 久久久精品电影| 欧美丰满老妇厨房牲生活| 国产精品久久久久久超碰| 欧美日韩精品二区| 福利视频第一区| 国产精品久久色| 久久精品99国产精品酒店日本| 久久99精品久久久久久噜噜| 日韩视频免费观看| 在线视频亚洲欧美| 欧美极品美女电影一区| 在线看日韩欧美| 97久久久久久| 国产91成人video| 在线一区二区日韩| 中文字幕欧美日韩va免费视频| 日韩在线免费av| 亚洲欧美日韩爽爽影院| 日本午夜在线亚洲.国产| 亚洲第一色中文字幕| 92版电视剧仙鹤神针在线观看| 久久久久久中文| 亚洲性av在线| 国产日韩专区在线| 久久久999国产| 91免费精品国偷自产在线| 亚洲自拍偷拍福利| 2019中文字幕在线| 日韩av一区二区在线| 亚洲美腿欧美激情另类| 国产欧美一区二区三区在线看| 成年人精品视频| 国产精品久久精品| 亚洲成人激情视频| 国色天香2019中文字幕在线观看| 亚洲美女又黄又爽在线观看| 美日韩精品免费视频| 日韩欧美视频一区二区三区| 成人免费福利视频| 欧美另类暴力丝袜| 九九视频直播综合网| 国产精品一区二区性色av| 91久久久久久久久久久| 91精品国产自产91精品| 亚洲成人久久久久| 亚洲天堂第二页| 日本国产欧美一区二区三区| 亚洲视频一区二区| 欧美日韩午夜剧场| 亚洲肉体裸体xxxx137| 欧美日韩亚洲视频一区| 欧美高清理论片| 亚洲黄一区二区| 97久久精品人人澡人人爽缅北| 91精品国产乱码久久久久久久久| 日韩美女在线观看| 上原亚衣av一区二区三区| 日韩欧美中文在线| 亚洲欧美在线第一页| 国产精品久久久av久久久| 97色伦亚洲国产| 国产精品久久久久国产a级|