动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.Java Applet编程技巧.
.Java网络编程之传输控制协议(一).
.我的java开发环境配置.
.编写跨平台Java程序注意事项.
.Mysql的子类,专门验证登录 Pas.
.JAVA程序员必读.
.使用Log4j进行日志操作.
.如何寻一个类X实例中类的物理所在.
.几个常见的关于日期的问题解决方.
.The Model-View-Controller Arch.
.JAVA中最为关键的几个知识点.
.判断两个密码框里的值是否相等.
.全面接触Java集合框架.
.X3D实战基础讲座之十二.
.CallFlow Builder 建语音应用程序.
.WebWork的强大的验证器.
.企业应用Web服务安全:问题介绍(.
.struts2的struts.properties配置.
.Servlet简介.
.使用UML编写Java应用程序 (2)设计.

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

发表日期:2008-1-5 |



  量词(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 语句<-符号右边的代码并进行求值。
上一篇:JML起步--使用JML改进你的Java程序(1) 人气:471
下一篇:用Maven更好地跟踪项目的进展情况 人气:504
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-10 企业网站智能管理系统(TZIMS) v6
2008-10-10 拓文asp.net网站内容管理系统 v6
2008-10-10 动网论坛PHP版 v2.0++ Build 081
2008-10-10 免费时代CMS v5.0
2008-10-10 wodig第四季中文DIGG社区 v4.1 b
2008-10-10 老Y文章管理系统 v2.2 bulid 081
2008-10-10 魔法盒动感相册 ASP+SQL版 v2.0
2008-10-10 Asoft签到管理系统 v3.0 Pack1
2008-10-10 哥特人音乐网潮流留言本 v1.1
2008-10-11 联系人分组工具 v1.1 中文破解版
2008-10-11 FaceMelter变脸 v2.0 汉化破解版
2008-10-11 PathTracker道路跟踪仪 v1.2 破解
2008-10-11 Rooms手机聊天室 v0.6.7 破解版
2008-10-11 RemoteDesktop远程桌面 v1.0 破解
2008-10-11 ProRemote远程调音台 v1.0.1 破解
2008-10-11 PicShare照片共享 v1.0.0 破解版
2008-10-11 Photogene照片编辑器 v1.5 汉化破
2008-10-11 WriteRoom共享文档 v1.0 破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成