有效检查Java代码的三个工具

时间:2019-05-12 11:22:16下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《有效检查Java代码的三个工具》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《有效检查Java代码的三个工具》。

第一篇:有效检查Java代码的三个工具

有效检查Java代码的三个工具

Java项目最枯燥的一部分,也是程序员总是避而不谈的一部分,就是检查代码。为了区块括号、代码缩进、Javadoc注释以及命名约定而检查其他人的上千行代码的确是一件痛苦的事。更糟糕的是,通常代码的检查还受限于紧迫的项目进度。没有足够的时间对代码的细节进行评估,因此代码检查经常变成了对代码的美化练习。不管检查者有多么好的意图,优化和逻辑检查都退居次席。

Java代码分析器减轻了这样的痛苦

在面对这种情况的时候,Java代码分析器正是对症良药。这些工具尽可能地将代码检查过程自动化。留给人工来做的就只有检查类的缺陷以及核心逻辑并确定可能的优化方法。优化(去除不必要的实例化对象、检查数据库连接是否合理、确保数据在可能的情况下被缓存)对于任何代码通常会带来性能上的极大改进。

最近我接触了各种代码分析器。我觉得一个基本的最重要的功能是与常用IDE(如NetBeans、Eclipse、jEdit以及JDeveloper)的集成。有一些代码检查工具在查找错误方面很有效,但是它们需要你根据给出的错误行的行号手工来追踪错误。这样的工具使用起来太累人了。与IDE环境集成了的工具可以大大简化这个过程,因为代码检查的结果是由所使用的IDE显示的。你只需在错误上双击就可以在Java编辑器中到达错误代码所在的行

我的试用心得

在我试用过的工具中,我发现其中三个工具十分强大并合乎与IDE集成的标准,它们是: PMD、Checkstyle 和 Jalopy。

PMD和Checkstyle

根据PMD的文档,它会对代码中的如下部分进行检查:

未使用的本地变量

空的catch块

未使用参数

空if语句

重复的import语句

未使用的私有方法

可能是Singletons的类

短/长变量及方法名字

Checkstyle检查如下部分:

Javadoc注释

命名约定

标题

Import语句

体积大小

空白

修饰符

混合检查(包活一些有用的比如非必须的System.out和printstackTrace)

它们的作用

不像PMD,Checkstyle能够检查Javadoc注释;但是PMD提供了一项叫作CPD的很有用的功能,它检查代码的拷贝粘贴部分。我使用PMD找到的最频繁的错误是未使用的import语句,未使用的私有变量以及意外重复拼写。Checkstyle可以发现更多的错误。包括漏掉的Javadoc注释,超过80个字符的行、不合约定的变量名、用tab来代替空格等等。两个工具都允许创建自定义的规则。

如果想在你的组织中使用它们中的一个,Checkstyle似乎更好一些:它检查公司编码约定的大多数项目。如果增强代码质量是主要目标,那PMD是一个好的选择。但是如果你想要更多的功能并真正使用工具来修改代码,应该试试Jalopy。

Jalopy

Jalopy是一个易于配置的源代码格式程序,它能检测并修补Java代码中大量的习惯性缺陷。Jalopy更像一个代码整理器而不是检查器。Jalopy的插件现在已经支持大多数IDE,而且多数是无缝集成。我发现Jalopy特别强大,能够干许多很酷的事情。例如,它可以修改代码缩进、对齐括号、使行宽符合某个字符长度、插入相关的Javadoc注释以及对import语句排序。Jalopy最好的地方是超级自定义功能。一个简单的用户界面就可以让你选择Jalopy的所有功能的开关,不需要XML配置文件。

不要浪费资源

我建议大家使用这些工具来代替那些费时费力却收效甚微的人工代码检查工作。一旦使用这些工具将代码检查变成了一个相对轻松的任务,你就可以把代码检查作为一项普通工作而不是在项目结尾被进度逼得一团糟时做的事情。这些工具也提供了与Apache Ant的集成,因此你可以每天运行这些代码检查器,在编译或执行单元测试它们也能工作得很好。控制好你的代码,并交付那些你真的认为是高质量的东西。

第二篇:代码检查

代码检查

摘要:代码检查是白盒测试的一种静态测试方法,是众多软件测试方法中发现软件缺陷最有效的方法之一。本文结合国内外学者在相关领域的研究情况,介绍代码检查相关的基本概念、过程和分析方法。

关键字:白盒测试,代码检查,静态分析,检查规则

一、引言

按照测试时源代码是否可见,软件测试可以分为白盒测试和黑盒测试两类。

白盒测试(结构测试),即逻辑驱动的测试,是在了解程序内部结构的基础上,对程序的逻辑结构进行检查,从中获取测试数据。白盒测试关注的是测试用例执行的程度或覆盖程序逻辑结构的程度。白盒测试一般只应用于软件开发阶段。

白盒测试,又可按照是否需要运行程序,进一步细分为了静态测试和动态测试两种。通常情况下是按照先静态后动态测试顺序来实施。其中,静态测试包括代码检查、静态结构分析、代码质量度量等测试内容。静态测试既可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行。

代码检查是一种对程序代码进行静态检查。传统的代码检查是通过人工阅读代码的方式,检查软件设计的正确性;用人脑模拟程序在计算机中的运行,仔细推敲、校验和核实程序每一步的执行结果,进而判断其执行逻辑、控制模型、算法和使用参数与数据的正确性。

在实践中,代码检查比动态测试更有效率,能找到更多的缺陷,通常能发现30%~70%的逻辑设计和编码缺陷。代码检查非常耗费时间,而且需要专业知识和经验的积累。代码检查定位在编译之后和动态测试之前进行,在检查前,应准备好需求描述文档、程序设计文档、程序的源代码清单、代码编码标准和代码缺陷检查表等。

代码检查可以发现的软件问题包括:声明或引用错误、函数/方法参数错误、语句不可达错误、数组越界错误、控制流错误、界面错误和输入/输出错误等。

1、代码检查

代码检查包括桌面检查、代码走查和代码审查等方式,主要检查代码和设计的一致性,代码对标准地遵循、可读性,代码逻辑表达的正确性,代码结构的合理性等方面;发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型检查、程序逻辑检查、程序语法检查和程序结构检查等内容。下面对代码检查的三种具体方式进行介绍。

桌面检查

是一种传统的检查方法,由程序员检查自己编写的程序。程序员在程序通过编译之后对源代码代码进行分析、检验,并补充相关的文档,目的是发现程序中的错误。

代码走查

代码走查就是针对代码,在假想的输入情况下,逐行的浏览代码,走查代码中潜在的缺陷并记录结果的过程。

代码走查以小组会议方式进行,每小组3-5人。与代码审查不同的是,走查要求与会者扮演计算机的角色让测试用例沿被测程序的逻辑运行,是在模拟动态测试;而代码审查更多的是静态测试。

代码审查

代码审查是由一组人通过阅读、讨论和争议对程序进行静态分析的过程,以小组会的方式进行。

审查小组一般由若干程序员(包括程序代码的设计者)和代码检查人员组成。会前把设计规格说明书、控制流程图、程序文本以及要求、规范、错误检查清单交给与会者,开会时程序作者朗读解释程序,其他人则集中精力,捕捉程序在结构、功能、编码风格等方面的问题。

2、代码检查项

代码检查项即检查代码时,指定需要进行检查的内容。具体如:检查变量的交叉引用表;检查标号的交叉引用表;检查子程序、宏、函数;等价性检查;标准检查;风格检查;选择、激活路径;对照程序的规格说明,详细阅读代码,逐字逐句分析;补充文档。

检查项可以作为依据,用来编制代码规则、规范和缺陷检查表等。

3、编码规范

编码规范是程序编写过程中必须遵循的一套事先约定或者已经制度化、标准化的规则集,一般会详细的规定代码的语法规则和语法格式。

一个良好的编码规范能够带来许多好处:改善代码质量;提高开发进度;增进团队精神。对于软件开发而言,采用好的编程规范,虽然不能彻底杜绝糟糕的代码产生。但对于代码检查和将来的代码维护,仍然是意义重大的。

4、缺陷检查表

在进行人工代码检查时,使用代码缺陷检查表作为代码检查的参考依据。在软件测试项目实践中代码缺陷检查表又常被称作代码检查清单。

代码缺陷检查表中一般包括开发人员容易出错的地方和在以往的工作中遇到的典型错误。对应于不同的编程语言,代码缺陷检查表的具体内容将会有所不同。例如:对于C/C++语言代码缺陷检查表内容有以下几部分:文件结构;文件的版式;命名规则;表达式与基本语句;常量;函数设计;内存管理;C++函数的高级特性;类的构造函数、析构函数和赋值函数;类的高级特性;其他的常见问题等。

5、代码检查规则

在代码检查中,需要依据被测软件的特点,选用适当的标准与规范。在使用测试软件进行自动化代码检查或辅助代码检查时,测试工具需要内置许多编码规范。不同编程语言,对应的检查规范有所不同。针对与C/C++语言的规则有以下几类规则:通用规则、C++编码规则、C编码规则、Meyers-Klaus规则以及自定义规则。使用时,需要根据编程语言和被测程序的特点,选择适当的规则进行检查。

6、静态分析

静态分析是不执行程序,而分析程序代码的过程。源代码被静态分析器分析之后,得到的静态分析结果,通常可以表示成一棵静态语法树。其中包含了被测项目源代码的静态结构信息:基本代码成分、程序结构、语句结构、类型和模板等信息。

程序代码静态分析的结果能够给代码检查提供帮助。

三、代码检查过程

传统的代码检查是一种静态检查程序的测试方法,通常以团队的形式来进行。检查团队由程序作者,一个负责人,一个记录员以及一些检查员组成。首先需要一系列的准备工作,包括参与者的挑选和材料的准备。然后是个人准备阶段,每个小组成员各自熟悉材料。个人准备阶段后,就是实际的检查会议。在会议上,检查小组在假想的输入下,由程序作者带领,逐行的浏览代码,评审代码中潜在的缺陷。检查小组根据发现缺陷的严重程度和类型对其进行分类,并将问题记录下来供作者修正。会议后是作者的返工,作者汇报每个缺陷,最后确认每个缺陷已经被陈述过了。图 11为传统的代码检查过程。

图 1 代码检查过程示意图

代码检查过程中的两个重要阶段“个人准备”和“召开会议”阶段有以下注意事项:

1、“个人准备”阶段:

会前准备阶段是检查过程的一个关键阶段,因为如果检查者没有为检查做好充分的准备,检查效果会大打折扣。如果有检查人员没有做好准备,主审员可取消其代码检查资格,甚至取消这次检查会议。

检查人员要熟悉检查内容的相关文档,了解程序背景、设计思想和编程方法,在读懂、“吃”透代码的基础上,查出尽可能多的错误。

2、“召开会议”阶段:

参与会议的检查者应具有一定的专业技能和经验,缺乏经验的检查人员必然缺乏合适的领域知识来深入理解材料;

参与会议的检查者应做充分的个人准备,没有做充分准备的检查人员不能在检查会中做出实质性的贡献;

检查会议的速度应进行控制,如果试图在短时间内处理太多的材料,检查效果也会大打折扣。现在较为常见的代码检查速度上的建议为:汇编代码150行/小时,C语言150行/小时,而对于C++、Java这种面向对象语言,代码检查速度可以提高到200-300行/小时。

由此可见,代码检查适合于采用工具辅助的特性有:文档处理,个人准备,会议支持,数据收集。

文档处理

这是工具可支持的最明显的领域。传统的检查要求分发每份文档的复印件等,而将纸质的文档替换成计算机式的文档,不只是简单的介质变更,更是提供了一种契机——提高文档的可用性和表示性的机遇。

个人准备

首先,自动的缺陷检测可以用来发现简单的缺陷。如果简单问题能被自动发现,检查员就能专注于更加复杂/困难的缺陷,以及那些不能被自动发现的、潜在的、可能带来更大影响的问题。另外,自动化工具应该对个人准备阶段提供更多的帮助。例如,检查员可以利用检查表以及其它支持文档,并能很容易地交叉引用它们;还有些代码辅助理解工具,可为检查员理解程序、了解程序结构提供帮助。 会议支持

一些成员由于某些原因,可能没有花费足够的时间来进行准备,但他们仍然参加会议并试图掩盖他们的过失。项目管理人员可以使用计算机监控的个人准备时间信息,来剔除那些没有做好个人准备的成员,或者督促他们投入更多的努力。

召开会议时,检查员通常面对的是一堆枯燥的程序代码,如果在代码之外再结合一些图、表等便于分析、理解代码的信息,相信检查会议可以进行得更加有序和高效。

数据收集

代码检查一个重要的部分就是度量信息的收集,用来提供反馈以改进检查过程。度量信息包括会议时间、发现的缺陷、检查花费的总时间等。根据这些数据,可以来评价每一次代码审查的质量,进而给出关于代码审查的改进建议。

通过对检查过程的部分阶段提供计算机支持,代码检查可以进行得更加有效。使用计算机来支持检查过程,可以提高效率,并增加检查过程的严格性。

四、代码检查历史数据

代码检查中的历史数据本质是软件问题(缺陷)。按照不同的代码检查角度,存在多种对缺陷分类的方法。对过往发现的软件问题进行分析,总结出今后对于类似的代码需要按照某种规则来加以检查,这种的规则就是检查清单上的一条清单项,代码检查清单就是大量规则的集合。此外,由于软件问题总是以软件问题报告为载体形式出现,因此软件问题报告也被通俗的理解为代码检查历史数据。

下面对缺陷分类、代码检查清单和软件问题报告加以研究。

1、缺陷分类

关于缺陷分类存在以下几种常见的划分方式:

1)按缺陷出现的区域分类

这种分类方式是最常见的缺陷分类方式。按照出现区域将代码缺陷划分为变量级、属性级、函数/方法级和类级缺陷。其中,变量级、属性级和部分函数/方法级的缺陷,与传统的面向过程编程中的缺陷分类基本一致;而多数方法级缺陷和类级缺陷,则是针对面向对象技术编程特点提出的。

2)按检测内容分类

分为冲突、一致性问题两种。

冲突对应于文献[1]中的基于确定性“信念”的判定,而一致性问题则对应于基于可能性“信念”的判定。

3)按对代码的危害分类

按照对代码的危害,一般分为浪费时间和空间;语义混淆;暴露封装性,扩大使用权限;程序一致性问题;程序约束条件问题和空指针问题等。

2、代码检查清单(Checklist)

代码检查过程中,代码检查人员都会有一份代码检查清单。代码检查清单是一份为代码检查人员准备的缺陷检查表,检查表中开列所有可能与代码有关的缺陷,并注明了检查的内容、缺陷类型以及严重性。检查清单是检查代码的依据,代码检查人员根据它来发现并判断问题。代码检查清单中会逐条列出所有应该检查的缺陷种类,以及每条缺陷的各种特征,并且根据缺陷的严重程度和类型对其进行分类。通常每一条缺陷的特征描述如下:

1)缺陷描述:该缺陷的问题描述、举例说明,以及相应的正确形式;

2)缺陷出现的区域:分别为表达式级、语句级、声明级、模板缺陷、预处理缺陷、类级缺陷以及性能缺陷。表达式级、语句级、声明级以及预处理的缺陷,主要面向过程程序中的缺陷;模板缺陷、类级缺陷,则是针对面向对象软件的特点提出的;代码冗余等归为性能缺陷;

3)缺陷对代码的危害:代码中出现某种缺陷将会造成什么样的影响。

例如,检查表中一条缺陷的特征描述如下:

问题描述:指针所指内存释放后没有将指针赋为NULL。

举例说明:

char *p=(char *)malloc(100);strcpy(p, “hello”);free(p);//p所指的内存被释放,但是p所指的地址还是不变 …

if(p!=NULL)//没有起到防错的作用 { strcpy(p, “world”);//出错 }

正确形式:在释放内存的同时将指针置空。

char *p=(char *)malloc(100);strcpy(p, “hello”);free(p);p=NULL;//增加指针置空语句

if(p!=NULL){ strcpy(p, “world”);}

出现区域:语句级。

危害:指针被free释放后其地址并不会自动发生改变(非NULL),p成为了“野”指针,这种情况下再对p进行操作,很容易造成程序崩溃,后果非常严重。而代码检查清单正是由若干条这样的缺陷特征描述构成的。

3、软件问题报告(Software Problem Report)

在软件测试过程中,对于发现的每个软件问题(缺陷),都要进行记录该错误的特征和再现步骤等信息,以便相关人员分析和处理软件问题。为了管理测试发现的软件问题,通常要采用软件问题报告数据库,将每一个发现的软件问题输入到软件问题报告数据库中,软件问题报告数据库的每一条记录称为一个软件问题报告。

软件问题报告包括头信息、简述、操作步骤和注释。

头信息包括:被测试软件名称、版本号、缺陷或错误类型、可重复性、测试平台、平台语言、缺陷或错误范围。并要求填写完整和准确。

简述是对缺陷或错误特征的简单描述,可以使用短语或短句,要求简练和准确。

操作步骤是描述该缺陷或错误出现的操作顺序,要求完整、简洁和准确。对命令、系统变量、选项要用大写字母,对控件名称等要加双引号。

注释一般是对缺陷或错误的附加描述,一般包括缺陷或错误现象的图像,包括其他建议或注释文字。

软件问题报告是软件测试过程中最重要的文档之一。它记录了软件问题发生的环境,软件问题的再现步骤以及性质的说明,而且还可以跟踪软件问题的处理过程和状态。软件问题的处理进程从一定角度反映了测试的进程和被测软件的质量状况及改善过程。

五、代码检查规则管理的研究

1、潜在的编码规则和缺陷代码模式

潜在的编码规则(Implicit Coding Rules)和缺陷代码模式(Bug Code Pattern)是Tomoko MATSUMURA在文献[3,4]中针对代码检查实践,提出的两个相关的概念。

潜在的编码规则

潜在的编码规则包含以下几个特征:

1)不同于在开发启动时明确决定的“编码规范”的规则,这些规则在长期的测试/维护过程中是潜伏的,对这些规则的发现是不可预见的。

2)这些规则很少在设计文档或者特定的文档中被清楚的描述。他们通常只存在于开发人员、测试/维护人员的记忆中。换言之,是一种尚未系统化的经验积累和总结的结果。

3)不同于使用规范库的公用规则。对于特定的软件有其特定的规则,这也意味着对于不同的软件有不同的潜在的编码规则。

4)由于违反潜在的编码规则导致的缺陷通常情况下不是那么容易发现的。其中相当多一部分只在特定的罕见的情况下发生,所以在早期要想发现这些问题是很困难的。

5)目前,还不存在好的工具或者检查清单来发现违反潜在的编码规则的代码片段,通常的检查工具(例如PC-Lint、Purify)和通用的检查清单只能发现常见的问题。

6)为了减少违反潜在的编码规则的现象的发生,而进行重构通常很困难。要重构一个软件,准确理解代码是非常必要的,然而,老的系统太复杂,并且没有精确的文档和了

解系统的专业维护人员。总之,重构过期系统的代价很大,需要冒很大的风险。

缺陷代码模式:违反潜在的编码规则的编码模式。

缺陷代码模式不是肯定会导致缺陷的发生,一段符合缺陷代码模式的代码片段,并不意味着代码片段一定就有缺陷,缺陷代码模式只是疑似存在缺陷。另一方面,因为缺陷代码模式是静态的,没有考虑到代码片段之间的动态关联。需要代码检查人员或者维护人员把符合缺陷代码模式的代码片段提出来,并判断究竟是否存在缺陷。

在软件开发过程中发现和建立缺陷代码模式有三条主要途径。其一:在进行代码检查过程中,代码检查人员发现一个软件问题的同时,根据对该问题是否具备代表性和通用性等因素的考虑,确定是否建立一个缺陷代码模式;其二:当软件失效或者发生问题,检查对应的代码部分,发现并确定是否有潜在的编码规范与之相关;其三:分析现存的代码规范和积累的大量问题报告,从中提炼出潜在的编码规则。

在文献[3,4]中还给我们介绍了一个代码缺陷检测系统的大致工作流程,如2所示。

图2 缺陷检测模型系统的代码检查流程参考图

2、C++代码检查规则类型

1)规则层次

在代码检查工作中常常可以发现这样的现象:有些规则能在所有的项目中都能发现问题,另一些规则所能发现的问题只存在于某类项目中。

根据规则的这个特点,如图 33中所示,参考文献[2]中将代码检查规则分为两个层次:

公共规则(General checks):用于检查在大多数情况都有可能发生的缺陷。

项目相关规则(Project specific checks):用于在项目中检查可能的缺陷。

图 3 一个典型的代码检查规则清单节选图

在项目中积累了大量软件问题报告历史数据的支持下,可以从中进一步细化出与项目或开发人员相关的检查规则。

在学习任何一种计算机编程语言时,总是按照基本数据类型->表达式->语句->复杂语句->函数->整个程序体(类)的顺序逐步学习的。事实上软件正是按照这样的顺序自下而上逐层组建起来的,代码缺陷作为软件编程写时的一种异常情况,毫不例外也是按照这样层次的构建而成。在实际测试项目的代码检查过程中,我们发现在每个层次上都有可能存在潜在代码缺陷,要找到引起软件问题的根源,要求在尽可能低的层次上找到引发缺陷的代码。正因如此,非常有必要在C++语法的每个层次上都建立相应的检查元规则。

图4为一个代码检查规则体系模型图[2],图中展示了在代码检查项目开始前,通过逐级组合各种元规则和规则形成新的检查规则,最后形成了初始的检查清单。在项目实践中,经过对缺陷代码模式的推导,进而得到扩展的检查清单。初始检查清单和扩展检查清单本质上并没有什么区别,只是因为形成的时间不同。

图4 代码检查规则体系模型图

在检查代码时我们有时会想要定义一个带有否定意义的规则,如“在AA情况下如果没有BB,则可能存在一个问题”。这类检查规则采用自然语言描述比较容易,但是要用代码实现起来往往并不简单,并且对这类规则的定义和维护也比较麻烦。定义组合规则,是解决这类问题一种变通的方法。

下面简单介绍一下定义组合规则的原理。如图5中所示定义三个规则,“满足情况AA”对应规则R1,“满足在AA情况下出现BB”对应规则R2,将满足R1但不满足R2(即以!符号表示)组合则对应规则R3-“在AA情况下如果没有BB,则可能存在一个问题”。

图5 组合规则示例图

根据前面讨论,本文将代码检查的规则分类设计如下:

公共规则

定义针对函数体(含)以上层次的检查规则,在这些层次上出现的缺陷问题一般不容易精确到具体的代码行。

关键字规则

针对每个关键字定义的检查规则。由于关键字是C++语法中一种最普通的元素,单独使用关键字规则的意义不大,一般情况需要和语句、表达式规则或者复杂语句规则配合使用。

语句/表达式规则

针对基本语句类型或基本表达式定义的规则,满足对应结构的表达式,则可认为符合了相应的表达式规则。语句/表达式规则中可以包含多个关键字,在同一语句/表达式规则中包含的关键字地位是平等的,与检查的先后次序无关。

复杂语句块规则

针对条件、开关选择等多分支语句定义的规则,通常由关键字、语句/表达式进行组合来定义复杂语句块,并在定义时可以进行嵌套,在定义复杂语句块规则加入语句或表达式和复杂语句时需要考虑检查的先后次序。

高级组合规则

关键字规则、语句/表达式规则和复杂语句块规则合称为普通规则。

对于难以使用普通规则定义方式定义的复杂语义,需要定义高级组合规则。定义高级组合规则可以使用上面几种规则作为基本单元,也可以嵌套使用其它组合规则。

图6为一个由下至上、由多个缺陷代码模式组合形成的组合规则结构图。其中{}表示某条缺陷代码模式对应的规则。

图6 组合规则结构图

六、代码分析方法

1、静态分析

静态分析主要对源代码进行词法分析、语法分析,提取被分析程序的静态信息,所提取的静态信息是代码缺陷检测的基础。静态分析结果主要包括三部分信息:

程序定义信息:程序定义信息包含了程序中所有的定义和声明信息,如类定义、方法和数据成员的定义、方法内局部变量的定义等。

程序结构信息:主要指方法内的控制流信息和方法间的调用关系。静态分析器分析程序的语句分支、分支间的嵌套关系和方法调用,记录方法的控制流信息和调用信息,构造语法树。

分支内的变量操作:以方法控制流程中的分支为基本单元,记录每一分支中各语句对各变量施加的操作和操作序列。

2、数据流分析

数据流分析也是一种静态代码检查方法。它是在不通过计算机运行被测程序的条件下,利用预先进行静态分析后获取的信息,检测对变量的赋值与使用操作中,是否存在不合理情况,即找出被测程序中是否存在变量在使用前未被赋值;变量在两次赋值之间未被使用;一个变量在被赋值后是否未被使用等异常情况。

数据流分析目前的主要用途大多局限在编译器的实现和优化技术方面,而在代码检查系统中实用的数据流分析技术并不多见,主要集中在某几种缺陷检测上,如赋值引用异常检测以及内存错误检测,使用方式主要是定义数据流操作的符号,使用该符号系统构造数据流表达式(由数据操作符号构成的符号串),再分析该符号串来确定是否存在代码缺陷。

数据流分析包括以下两个步骤:一是分析程序的所有逻辑路径;二是对所有逻辑路径上的所有变量,分析其所有操作序列,然后将得到的操作序列输入自动机进行分析。因此数据流分析方法不可避免的存在以下缺点:

1)信息量多,上面所述的数据流分析方法是一种穷举法。事实上一个变量在大部分路径上存在问题的几率并不高,因此穷举每个变量的所有操作序列不可避免的要分析很多正确的信息,而且信息量巨大;

2)组合爆炸,当程序复杂度增长时,该分析方法的复杂度呈几何级数增长,并且当这种组合是建立在对所有逻辑路径、所有变量的穷举基础上时,如果不能找到一个非常高效的算法,数据流分析方法将是一个非常低效的方法;

3)实用性低,上述两点导致的数据流分析的实用性降低。

为缓解这些的缺点,数据流分析过程有许多改进方法,但实现都具有一定难度。本系统中数据流分析不是重点,采取的策略是尽可能简化数据流分析的过程,或者在可能的情况下尽量避免数据流分析。

第三篇:JAVA代码注释规范

JAVA代码注释规范

一、规范存在的意义

1.好的注释规范可以让人一眼看明白这是干什么的,特别是对于我们这种行业;共同合作完成一个项目需要分工明确,所以也需要有明了的注释规范。

2.正确的应用注释规范可以增加代码的可读性、理解性。3.好的代码规范可以提高团队的开发效率,从而节省时间。4.长期的坚持代码规范可以让程序员养成一个良好的习惯,甚至锻炼出思维。

二、命名规范

1.一般概念

1)尽量使用完整的英文描述。2)采用相对好理解的术语。

3)采用骆驼命名的规范使名字增加可读性。4)尽量少用缩写提高可读性。5)避免名字过长。

6)避免使用类似的名字。7)避免使用特殊符号。2.主要的运用

1)类(class)的命名

2)接口(interface)的命名 +方法(method)的命名 3)参数(param)的命名

三、注释规范

1.一般概念

1)注释应该增加代码的清晰度 2)保持代码的整洁

3)在写代码之前或同时注意写上注释

4)注释出为什么做这件事,做这件事的结果 2.注释那些部分

1)java文件:版权信息、创建时间、创建人 2)类:目的、所完成功能、版权信息、创建人 3)方法:参数含义、返回值 4)属性:字段描述

5)接口:目的、创建人、版本号、创建时间

四、代码格式规范

1.单行注释://注释内容,一般与代码后空4-8格,注释必须对齐 2.块状注释:/*注释内容*/,一般是注释从以/*开始,以*/结束中的所有内容。3.文档注释:/**......*/所以注释文 档必须书写在类、域、构造函数、方法,以及字段(field)定义之前.注释文档由两部分组成——描述、块标记。4.javadoc注释标签

@author 对类的说明 标明开发该类模块的作者

@version 对类的说明 标明该类模块的版本

@see 对类、属性、方法的说明 参考转向,也就是相关主题

@param 对方法的说明 对方法中某参数的说明

@return 对方法的说明 对方法返回值的说明

@exception 对方法的说明 对方法可能抛出的异常进行说明

五、java注释具体实现

1.源文件注释

/** *文件名 *创建人 *创建时间 *修改人 *描述 *版本号 */ 2.类注释

/** *对此类的描述信息 *创建人 *版本号 *创建时间 */ 3.方法的注释

/** *方法的用处 *该方法的参数列 *该方法返回的值 */ 4.属性的注释

/** *字段的描述 */ 5.接口注释

/** *对此接口的描述 *创建人 *创建时间 *版本号 */ 6.构造方法注释

/** *描述该构造方法的用处 *该构造方法的参数列 *参数的类型 */

六、Jsp代码格式规范

1.多行注释:,一般是注释从以结束中的所有内容。

2.文本注释:<%--内容--%>,主要是对该页面的一些描述,目的、创建人、创建时间、版本号、文件名、备注、修改人等.例如: <%---创建人-创建时间-版本号-文件名-备注-修改人--%> 3.伪劣标签注释:<% java语句块 %> 例如: <% JAVA代码块 %> 4.单行注释://注释内容,一般与代码后空4-8格,注释必须对齐

七、JS代码格式规范

1.文本注释:/** 注释内容 **/,主要是对该页面的一些描述,目的、创建人、创建时间、版本号、文件名、备注、修改人等.也可以用于注释代码块。例如: /** *创建人 *创建时间 *版本号 *文件名 *备注 *修改人 **/

2.文本注释:/** 内容 */ ,主要是对该页面的一些描述,目的、创建人、创建时间、版本号、文件名、备注、修改人等.也可以用于注释代码块。例如: /** *创建人 *创建时间 *版本号 *文件名 *备注 *修改人 */ 3.单行注释: //注释内容,一般与代码后空4-8格,注释必须对齐 4.多行注释: /* 注释内容 */,一般是注释从以/* 开始,以*/结束中的所有内容。

八、JS注释具体实现 1.文件注释

/** *对此文件的描述信息 *创建人 *版本号 *创建时间 */ 2.方法的注释

/** *方法的用处 *该方法的参数列 *该方法返回的值 */ 3.模块的注释

/** *模块名称

*模块的用处

*/

第四篇:java流实验内容及代码

实验7 流(2学时)

一、实验目的1.熟悉流类库中各种常用流的使用方法。

2.能够使用流类实现基本的文件读写。

二、实验内容

1.编写程序,在控制台窗口提示输入两个整数,然后接收这两个整数,并输出它们的和。(要求:键盘输入通过流封装System.in获取,不要使用Scanner类)

import java.io.*;System.out.println(x);System.out.println(“y”);public class Num1 {n=in.readLine();public static void main(String []args)y=Integer.parseInt(n);{System.out.println(y);int x=0,y=0;}catch(IOException e)BufferedReader in=new BufferedReader({

newSystem.out.println(“error”);InputStreamReader(System.in));}

String n;int s=x+y;

try{System.out.println(s);System.out.println(“x”);}

n=in.readLine();}

x=Integer.parseInt(n);

2.设计学生类Student,属性:编号(整型);姓名(字符串),成绩(整型)。编写一个程序:要求:(1)输入3个学生的姓名和成绩,将其姓名和成绩保存到data.txt中;(2)然后从该文件中读取数据,求得这三个学生的平均成绩。

import java.io.*;DataOutputStream dout = newDataOutputStream(public class num2 {newpublic static void main(String[]args)FileOutputStream(“D:data.txt”));{String n;

BufferedReader in=new BufferedReader(for(int i=0;i<5;i++)new{

InputStreamReader(System.in));n=in.readLine();

int num=Integer.parseInt(n);try{String name=in.readLine();

n=in.readLine();int grade=Integer.parseInt(n);dout.writeBytes(num+“rn”);dout.writeBytes(name+“rn”);dout.writeBytes(grade+“rn”);}dout.close();}catch(IOException e1){int num=Integer.parseInt(n);

n=din.readLine();String name=n;n=din.readLine();int grade=Integer.parseInt(n);ave+=grade;}System.out.println(“平均成绩”+ave*1.0/5);System.out.println(“文件写入失败”);}try{DataInputStream din =new DataInputStream(new FileInputStream(“D:data.txt”));int ave=0;String n;for(int i=0;i<5;i++){n=din.readLine();

三、实验要求

完成程序设计并提交实验报告。

在“);失败”);} }

}catch(FileNotFoundException e){System.out.println(“文件不存}catch(IOException e2){System.out.println(”文件读取}

第五篇:ATM自助取款机系统java代码

public void actionPerformed(ActionEvent e)

//界面显示控制 {

String IC_Number=“";

String password=”“;String IC_No=”“;

z30.setVisible(false);

float

leftmoney=0;

float

moneys=0;

float mon=0;

float money1=0;

float money2=0;

if(true)

{int No_50=0,No_100=0;

String strin=”select NO_50,NO_100 from ATM ATM_ID='123456789'“;ResultSetrsSQLSelect=executeQuery(strin);try{ if(rsSQLSelect.next())

{

No_50=Integer.parseInt(rsSQLSelect.getString(”NO_50“));

No_100=Integer.parseInt(rsSQLSelect.getString(”NO_100“));

where

}

}

catch(Exception er){System.out.println(”查询ATM机信息出错!“);}

if(No_50==0&&No_100==0)

{

z1.setVisible(false);

t1.setText(”对不起,本ATM自动取款机暂停服务!“);cl.show(c,”1“);

}

}

cl.show(c,”1“);

if(e.getSource()==z1)

{

t3.setText(”“);

text1.setText(”“);cl.show(c,”2“);

}

if(e.getSource()==z4||e.getSource()==z6||e.getSource()==z11||e.getSource()==z16||e.getSource()==z18||e.getSource()==z22)

{ closeDBConnection();cl.show(c,”1“);

}

if(e.getSource()==z2)

{ closeDBConnection();System.exit(0);

}

if(e.getSource()==z3){ IC_Number=text1.getText().trim();

if(getname(IC_Number))

{z5.setVisible(true);

pw1.setVisible(true);

t4.setVisible(true);

pw1.setText(”“);

t5.setText(”“);cl.show(c,”3“);

}

else

{

t3.setText(”您输入的卡号不存在,请重新输入!“);cl.show(c,”2“);

}

}

if(e.getSource()==z5){

password=pw1.getText().trim();IC_Number=text1.getText().trim();

if(!login(IC_Number,password))

{

t5.setText(”您输入的密码错误,请重新输入!“);

pw1.setText(”“);

n--;cl.show(c,”3“);

}

else

{

t5.setText(”“);cl.show(c,”4“);

}

if(n<0)

{

n=2;

t5.setText(”您已经三次输入错误密码,谢谢您的使用,欢迎下次光临!“);

z5.setVisible(false);

pw1.setVisible(false);

t4.setVisible(false);cl.show(c,”3“);

}

}

if(e.getSource()==z7)

{

t33.setText(”“);cl.show(c,”5“);

}

if(e.getSource()==z8)

//余额查询 { DBAccess d=new DBAccess();

String str3=”“;

String stri=”“;IC_Number=text1.getText().trim();

t29.setText(IC_Number);leftmoney=getmoney(IC_Number);

t30.setText(Float.toString(leftmoney));stri=”select bank_name from IC,bank where IC.bank_NO=bank.bank_NO and IC_ID='“+IC_Number+”'“;ResultSetrsSQLSelect=d.executeQuery(stri);try{

if(rsSQLSelect.next())

{

str3=rsSQLSelect.getString(”bank_name“);

//d.commit();

}

} catch(Exception er){}

t32.setText(str3);cl.show(c,”10“);

}

if(e.getSource()==z9)

{

t23.setText(”“);cl.show(c,”9“);

}

if(e.getSource()==z10)

{

t28.setText(”“);cl.show(c,”11“);

}

if(e.getSource()==z12){ DBAccess d=new DBAccess();IC_Number=text1.getText().trim();fetchmoney=Integer.parseInt(text2.getText());

if(fetchmoney<=0)

{

t9.setText(”取款金额非法!请重新输入!“);

text2.setText(”“);cl.show(c,”6“);

return;

}

if(fetchmoney>1000)

{

t9.setText(”每次交易金额最大为1000元!“);

text2.setText(”“);cl.show(c,”6“);return;

}

if(fetchmoney%50!=0)

{

t9.setText(”取款金额只能为50的倍数!“);

text2.setText(”“);cl.show(c,”6“);return;

} leftmoney=getmoney(IC_Number);

if(fetchmoney>leftmoney)

{

t9.setText(”您的余额不足,请重新输入取款金额!“);

text2.setText(”“);cl.show(c,”6“);return;

}

int No_50=0,No_100=0,x_50=0,x_100=0,mo=0;

String str1=”select NO_50,NO_100 from ATM where ATM_ID='123456789'“;ResultSetrsSQLSelect=d.executeQuery(str1);try{ if(rsSQLSelect.next())

{

No_50=Integer.parseInt(rsSQLSelect.getString(”NO_50“));

No_100=Integer.parseInt(rsSQLSelect.getString(”NO_100“));

}

}

catch(Exception er){System.out.println(”查询ATM机信息出错!“);}

x_100=fetchmoney/100;

if(No_100

{ mo=fetchmoney-No_100*100;

x_50=mo/50;

if(x_50>No_50)

{

t9.setText(”取款机现钞不足!“);

text2.setText(”“);cl.show(c,”6“);

return;

}

else

{

No_50=No_50-x_50;

No_100=0;

}

}

else

{

No_100=No_100-x_100;

x_50=(fetchmoney-x_100*100)/50;

if(x_50>No_50)

{

t9.setText(”取款机50面值现钞不足!“);

text2.setText(”“);cl.show(c,”6“);

return;

}

else

{No_50=No_50-x_50;}

}

String str2=”update ATM set NO_50=“+No_50+” where ATM_ID='“+ATM_id+”'“;

String str3=”update ATM set NO_100=“+No_100+” where ATM_ID='“+ATM_id+”'“;d.executeUpdate(str2);d.executeUpdate(str3);

setmoney(fetchmoney,IC_Number);

t12.setText(Float.toString(fetchmoney));cl.show(c,”7“);

text2.setText(”");

下载有效检查Java代码的三个工具word格式文档
下载有效检查Java代码的三个工具.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    Java程序设计课程实验代码及答案

    Java程序设计课程实验 上机实践1 初识JAVA ................................................................................................................. 3 实......

    java教学计划编制的全部代码

    package curriculumProject; //非连通图的深度优先搜索遍历和广度优先搜索遍历 import linearList.Queue.SeqQueue; //顺序循环队列类 public abstract class AbstractG......

    三个工具助力年会筹办

    500强HR推荐:三个工具助力年会筹办 【年终HR火线救急】蛇年年底已至,HR们愈发忙碌。从年底招聘到反跳槽,从绩效考核到年终奖制定,从2013年工作总结到2014年工作计划,老总与全公司......

    别了,格律检查工具!

    别了,格律检查工具! 中国青年文学网——国内最大的青年文学交流平台 《别了,格律检查工具!》——诗词规则及标准的讨论! 终 于有人跟我有同样的观点了!其实想想都觉得可笑,一首诗词......

    正版软件检查工具网络版使用手册

    正版软件检查工具网络版 用户使用手册 正版软件检查工具网络版 ...................................................................... 1 用户使用手册 .....................

    三个规范检查 文档

    学生管理规范资料准备 三系部 1、两操 卫生 迟到 文明班级 文明宿舍、雅室大赛检查评比资料,宿舍晚间考勤表,周末点名表、请假条、出门条存根。 2、系部学生管理工作计划、总......

    Java程序员面试宝典 - Java代码查错(大全5篇)

    JAVA代码查错 1.abstract class Name { private String name; public abstract boolean isStupidName(String name) {} }大侠们,这有何错误?答案: 错。abstract method必须......

    java各个设计模式代码实现总结

    第一章静态工厂设计模式 默认的包,只是包内共享。Protected的是包内和子类供共享。 1、 要生产的产品,要设计成接口 (1)public interface IMusicBox { public void playBox();......