Java编程的标准之JAVA编程规范.docx
- 文档编号:30331363
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:58
- 大小:61.37KB
Java编程的标准之JAVA编程规范.docx
《Java编程的标准之JAVA编程规范.docx》由会员分享,可在线阅读,更多相关《Java编程的标准之JAVA编程规范.docx(58页珍藏版)》请在冰豆网上搜索。
Java编程的标准之JAVA编程规范
Java编程的标准之JAVA编程规范
简介
本文提供一整套编写高效可靠的Java代码的标准、约定和指南。
它们以安全可靠的软件工程原则为基础,使代码易于理解、维护和增强。
而且,通过遵循这些程序设计标准,你作为一个Java软件开发者的生产效率会有显著提高。
经验证明,若从一开始就花时间编写高质量的代码,则在软件开发阶段,对代码的修改要容易很多。
最后,遵循一套通用的程序设计标准将带来更大的一致性,使软件开发团队的效率明显提高。
最根本的原则:
运用常识。
当找不到任何规则或指导方针,当规则明显不能适用,当所有的方法都失效的时侯:
运用常识并核实这些基本原则。
这条规则比其它所有规则都重要。
常识是必不可少的。
程序设计标准
Java的程序设计标准很重要,原因在于它将提高开发团队各成员的代码的一致性。
一致性的提高会使代码更易理解,这意味着它更易开发和维护。
从而降低了应用程序的总开发成本。
你必须牢记的是:
你的Java代码在你已离开并开始另一个项目之后,会保留相当长的一端时间。
因此开发过程中一个很重要的目标就是要确保在开发成员或开发团队之间的工作可以顺利交接,不必花很大的力气便能理解已编写的代码,以便继续维护和改进以前的工作。
如果代码难以理解,很有可能被废弃和重写。
命名约定
我们将在整个标准中讨论命名约定,所以让我们先讨论几个基本点:
1.使用可以准确说明变量/字段/类的完整的英文描述符。
例如,采用类似firstName,grandTotal或CorporateCustomer这样的名字。
虽然象x1,y1或fn这样的名字很简短,输入起来容易,但是我们难以知道它们代表什么、结果是什么含义,因而使代码难以理解、维护和改进。
2.采用该领域的术语。
如果用户称他们的“客户”(clients)为“顾客”(customers),那么就采用术语Customer来命名这个类,而不用Client。
许多程序开发者会犯的一个错误是,不去使用工业或领域里已经存在着很完美的术语时,却生造出一些普通词汇。
3.采用大小写混合,提高名字的可读性。
一般应该采用小写字母,但是类和接口的名字的首字母,以及任何中间单词的首字母应该大写。
4.尽量少用缩写,但如果一定要使用,就要谨慎地使用。
这意味着应该保留一个标准缩写的列表,明智地从中选取,并且在使用时保持一致。
例如,想对单词“number”采用缩写,那么可从nbr,no或者num中选取一个,说明一下采用了哪一个(具体是哪个倒无所谓),并且只使用这一种形式。
5.避免使用长名字(最好不超过15个字母)。
虽然PhysicalOrVirtualProductOrService看起来似乎是个不错的类名,但是这个名字太长了,应该考虑重新给它起个短一点的名字,比如象Offering。
6.避免使用相似或者仅在大小写上有区别的名字。
例如,不应同时使用变量名persistentObject和persistentObjects,以及anSqlDatabase和anSQLDatabase。
7.避免使用下划线作为名字的首末字母。
以下划线为首末字母的名字通常为系统保留,除预处理定义之外,一般不用作用户命名。
更重要的是,下划线经常造成麻烦而且难输入,所以尽量避免使用。
注释约定
我们还会对注释约定进行讨论,所以,我们先谈谈一些基本点:
1.注释应该增加代码的清晰度。
代码注释的目的是要使代码更易于被同时参与程序设计的开发人员以及其他后继开发人员理解。
2.如果你的程序不值得注释,那么它也很可能也不值得运行[NAG95]。
3.避免使用装饰性内容,也就是说,不要使用象广告横幅那样的注释语句。
二十世纪六十年代和七十年代,COBOL程序员们养成了画框的习惯,典型的是用星号将他们的内部注释圈起来。
当然,这给他们的艺术创造欲一个发泄方式,但是坦白地说,这只是在大量浪费时间,并不能给最终的产品增加丝毫价值。
要写的是清晰的代码,不是外表可爱的代码。
此外,由于有些字体的显示和打印是成比例的,但有些又不是,所以无法将那些框排整齐。
4.保持注释的简洁。
最好的注释应该是简单明了的注释。
注释不必洋洋洒洒,只需提供足够的信息,使别人能够理解你的代码。
5.先写注释,后写代码。
写代码注释的最好方法是在写代码之前就写注释。
这使你在写代码之前可以想想代码的功能和运行。
而且这样确保不会遗漏注释。
另一种方法是边写代码边写注释。
因为注释可以使代码更易理解,所以在程序开发的过程中,也可以利用这一点。
如果打算花些时间写注释,那么至少你应从这个过程中获得些什么[AMB98]。
6.注释信息不仅要包括代码的功能,还应给出原因。
例如,下面例1中的代码显示金额在$1,000以上(包括$1,000)的定单可给予5%的折扣。
为什么要这样做呢?
难道有一个商业法则规定大额定单可以得到折扣吗?
这种给大额定单的特殊是有时限的呢,还是一直都这样?
最初的程序设计者是否只是由于慷慨大度才这样做呢?
除非它们在某个地方(或者是在源代码本身,或者是在一个外部文档里)被注释出来,否则你不可能知道这些。
例1.1
if(grandTotal>=1000.00)
{
grandTotal=grandTotal*0.95;
}
Java注释语句类型
Java有三种注释语句风格:
以/**开始,*/结束的文档注释,以/*开始,以*/结束的C语言风格注释,以及以//开始,代码行末尾结束的单行注释。
下表是对各类注释语句建议用法的一个概括,也给出了几个例子。
注释语句类型
用法
示例
文档注释
在接口、类、成员函数和字段声明之前紧靠它们的位置用文档注释进行说明。
文档注释由javadoc处理,为一个类生成外部注释文档,如下所示。
/**
Customer(顾客).顾客是指作为我们的服务及产品的销售对象的任何个人或组织。
@authorS.W.Ambler
*/
C语言风格注释
采用C语言风格的注释语句将无用的代码注释掉。
保留这些代码是因为用户可能改变想法,或者只是想在调试中暂时不执行这些代码。
/*
这部分代码已被它前面的代码替代,所以于1999年6月4日被B.Gustafsson注释掉。
如果两年之后仍未用这些代码,将其删除。
...(源代码)
*/
单行注释
在成员函数内部采用单行注释语句对业务逻辑、代码片段和临时变量声明进行说明。
//因为让利活动
//从1995年2月开始,
//所以给所有超过$1000的
//发货单5%的折扣。
一件很重要的事情是,你的机构应该制订一套如何使用C语言风格注释和单行注释的标准,并始终严格遵守。
使用一种注释方式来说明业务逻辑,使用另一种方式注释掉旧的代码。
业务逻辑采用单行注释,因为这样可以将注释和代码放在同一行(这又叫做“内联”)。
采用C语言风格的注释屏蔽掉旧的代码,因为这样可以同时注释掉数行。
C语言风格注释看起来很象文档注释,所以为了防止混淆,不应在别处使用。
注意行末注释。
[MCO93]强烈反对采用行内注释,即在一行的末尾加上注释。
他指出,这种注释必须在代码的右端对齐,这样才能避免代码结构看起来混乱。
结果,这些注释的格式难以划一。
“如果你使用了很多这样的注释,则要花时间去将它们排列整齐。
这些时间并没有花在更多地了解代码上,而完全花在了敲击空格键和制表符这种冗长乏味的工作上。
”他又指出,行末注释也难以维护。
因为当该行程序的代码加长时,它们会将这些注释挤出该行,如果你将它们排齐了,你不得不对余下的注释做同样的工作。
快速浏览javadoc
Sun公司的JavaDevelopmentKit(JDK)中有一个名为javadoc的程序。
它可以处理Java的源代码文件,并且为Java程序产生HTML文件形式的外部注释文档。
Javadoc支持一定数目的标记,标识注释文档中各段起始位置的保留字。
详情请参考JDKjavadoc文档。
标记
用于
目的
@authorname
类、
接口
说明特定某一段程序代码的作者。
每一个作者各有一个标记。
@deprecated
类、
成员函数
说明该类的应用程序编程接口(API)已被废弃,因此应不再使用。
@exceptionnamedescription
成员函数
说明由成员函数发出的异常。
一个异常采用一个标记,并要给出异常的完整类名。
@paramnamedescription
成员函数
用来说明传递给一个成员函数的参数,其中包括参数的类型/类和用法。
每个参数各有一个标记。
@returndescription
成员函数
若成员函数有返回值,对该返回值进行说明。
应说明返回值的类型/类和可能的用途。
@since
类、成员函数
说明自从有JDK1.1以来,该项已存在了多长时间。
@seeClassName
类、接口、成员函数、字段
在文档中生成指向特定类的超文本链接。
可以并且应该采用完全合法的类名。
@seeClassName#memberfunctionName
类、接口、成员函数、字段
在文档中生成指向特定成员函数的超文本链接。
可以并且应该采用完全合法的类名。
@versiontext
类、接口
说明特定一段代码的版本信息。
你注释代码的方式很大地影响着你的工作效率以及所有维护改进代码的后继开发者的工作效率。
在软件开发过程中及早注释代码,会促使你在开始撰写代码之前仔细考虑这些代码,从而带来更高的工作效率。
而且,当你重新阅读数天前或者数星期前所写的代码时,你可以很容易地判断出当时你是怎么想的,因为这一切都有记录。
成员函数标准
切记:
你今天所写的代码可能在今后的数年里仍在使用,而且很有可能由其他人来维护和改进。
应尽可能使你的代码“整洁”易懂,因为这会使代码易于维护和改进。
命名成员函数
成员函数的命名应采用完整的英文描述符,大小写混合使用:
所有中间单词的第一个字母大写。
成员函数名称的第一个单词常常采用一个有强烈动作色彩的动词。
示例:
openAccount()
printMailingLabel()
save()
delete()
这种约定常常使人一看到成员函数的名称就能判断它的功能。
虽然这种约定要使开发者多做一些输入的工作,因为函数名常常较长,但是回报是提高代码的可理解性。
命名存取成员函数
在后续章节中,我们将更详细地讨论获取和存放字段值(字段/属性)的存取成员函数。
下面将概括一下存取函数的命名约定。
获取函数
获取函数作为一个成员函数,返回一个字段的值。
除了布尔字段之外,应采用get作为字段的前缀;布尔字段采用is作为前缀。
示例:
getFirstName()
getAccountNumber()
isPersistent()
isAtEnd()
遵循这个命名约定,显然,成员函数将返回对象的字段,布尔型的获取函数将返回布尔值“真”或者“假”。
这个标准的另一个优点是:
它遵循beansdevelopmentkit(BDK)对获取成员函数采用的命名约定[DES97]。
它的一个主要的缺点是get是多余的,需要额外的录入工作。
获取函数的另一种命名约定。
Has和Can
基于正规英文约定的一个可行的取代方法是,用has或者can来代替布尔型获取函数的is前缀。
例如,形如hasDependents()和canPrint()的获取函数,读起来就发现它们意义更加明确。
这种方法存在的问题是BDK目前还不支持这种命名方法。
可以将isBurdenedWithDependents()和isPrintable()这些成员函数重新命名。
设置函数
设置函数,也叫变值函数,是可以修改一个字段值的成员函数,。
无论何种字段类型,都要在字段名的前面加上set前缀。
示例:
setFirstName(StringaName)
setAccountNumber(intanAccountNumber)
setReasonableGoals(VectornewGoals)
setPersistent(booleanisPersistent)
setAtEnd(booleanisAtEnd)
按照这种命名约定,显然是一个成员函数设定一个对象的字段值。
这个标准的另一个优点是:
它遵循beansdevelopmentkit(BDK)对设置函数采用的命名约定[DES97]。
它的一个主要的缺点是set是多余的,需要额外的录入。
命名构造函数
构造函数是在一个对象初次生成时,完成所有必需的初始化的成员函数。
构造函数与它所属类的名字总是相同的。
例如,类Customer的构造函数是Customer()。
注意大小写一致。
示例:
Customer()
SavingsAccount()
PersistenceBroker()
这个命名约定由Sun公司设定,必须严格遵守。
成员函数的可见性
良好的程序设计应该尽可能减小类与类之间耦合,所遵循的经验法则是:
尽量限制成员函数的可见性。
如果成员函数没必要公有(public),就定义为保护(protected);没必要保护(protected),就定义为私有(private)。
可见性
说明
正确用法
public
公有成员函数可被任何其它对象和类的成员函数调用。
当该成员函数必须被该函数所在的层次结构之外的其他对象和类在访问时。
protected
被保护的成员函数可被它所在的类或该类的子类的任何成员函数调用。
当该成员函数提供的行为被它所在类的层次结构内部而非外部需要时。
private
私有成员函数只可以被该类所在的其它成员函数调用,该类的子类不可以调用。
当该成员函数所提供的行为明确针对定义它的类时。
私有成员函数常常是重新分配要素的结果。
重新分配要素又叫“重组”,指类内其它成员函数封装某一个特定行为的做法。
注释成员函数
如何注释一个成员函数常常成为判断函数是否可被理解,进而可维护和可扩展的决定性因素。
成员函数的函数头
每一个Java成员函数都应包含某种称之为“成员函数文档”的函数头。
这些函数头在源代码的前面,用来记录所有重要的有助于理解函数的信息。
这些信息包含但不仅仅局限于以下内容:
1.成员函数做什么以及它为什么做这个。
通过给一个成员函数加注释,让别人更加容易判断他们是否可以复用代码。
注释出函数为什么做这个可以让其他人更容易将你的代码放到程序的上下文中去。
也使其他人更容易判断是否应该对你的某一段代码加以修改(有可能他要做的修改与你最初为什么要写这一段代码是相互冲突的)。
2.哪些参数必须传递给一个成员函数。
还必须说明,如果带参数,那么什么样的参数必须传给成员函数,以及成员函数将怎样使用它们。
这个信息使其他程序员了解应将怎样的信息传递给一个成员函数。
在(第1.4.2节“快速浏览javadoc”)中讨论的javadoc@param标识便用于该目的。
3.成员函数返回什么。
如果成员函数有返回值,则应注释出来,这样可以使其他程序员正确地使用返回值/对象。
在(第1.4.2节“快速浏览javadoc”)里讨论的javadoc@return标识便用于此目的。
4.已知的问题。
成员函数中的任何突出的问题都应说明,以便让其他程序开发者了解该成员函数的弱点和难点。
如果在一个类的多个成员函数中都存在着同样的问题,那么这个问题应该写在类的说明里。
5.任何由某个成员函数抛出的异常。
应说明成员函数抛出的所有异常,以便使其他程序员明白他们的代码应该捕获些什么。
在(第1.4.2节“快速浏览javadoc”)中讨论的javadoc@exception标识便用于此目的。
6.可见性决策。
如果你觉得你对于一个成员函数可见性的选择会遭到别人的质疑,例如可能你将一个成员函数设为公共的,但是却没有任何对象调用该成员函数,那么应说明你的决定。
这将帮助其他开发者了解你的想法,使他们不必浪费时间操心考虑你为什么要选择一种有疑问的东西。
7.成员函数是如何改变对象的。
若一个成员函数修改了一个对象,例如一个银行帐户的成员函数withdraw()修改了帐户余额,那么就需要说明。
这种信息必须给出,使其他Java程序员能准确地知道一个成员函数调用将如何影响目标对象。
8.避免使用含有信息的函数头。
比如说作者、电话、创建和修改日期、单元(或者文件名)的位置,因为这些信息很快就会过时。
将版权所有者信息放到单元的最后。
例如,读者不会想要翻过两三页诸如“版权所有”等对理解程序毫无帮助且(或)不提供任何编程信息的文本。
避免使用垂直滚动条或者关闭的文本框或对话框,这些东西只会增加视觉干扰,而且较难保持一致。
采用一个配置管理工具来保存单元历史。
9.如何在适当情况下调用成员函数的例子。
最简单的确定一段代码如何工作的方法是看一个例子。
考虑包含一到两个如何调用成员函数的例子。
10.可用的前提条件和后置条件。
前提条件是指一个成员函数可正确运行的限制条件;后置条件是指一个成员函数执行完以后的属性或声明[MEY88]。
前提条件和后置条件以多种方式说明了在编写成员函数过程中所做的假设[AMB98],精确定义了一个成员函数的应用范围。
11.所有并行事件。
对众多程序开发者来说,并行性是一个新而复杂的概念;对有经验的并行性程序开发者来说,并行性也是一个老但却复杂的课题。
最终结果是,如果应用了Java的并行编程特性,那么应在程序中详细地将其注释出来。
[LEA97]建议,当一个类既包含了同步也包含了非同步的成员函数时,必须注释出成员函数依赖的执行上下文,尤其是当函数可被无约束访问时。
这样可以让其他开发者安全地使用你的成员函数。
当一个采用了Runnable接口的类的设置函数(即可更新一个字段的成员函数)没有同步时,应说明这样做的理由。
最后,如果覆盖或重载一个成员函数,并且修改了它的同步性时,也应说明理由。
仅当注释增加代码的清晰度时,才应加上注释。
对于每个成员函数,并非要说明以上所有部分,因为对于每一个成员函数来说,并不是以上所有的部分都适用。
但是,对于所写的每个成员函数要说明以上的部分内容。
内部注释
除成员函数注释以外,在成员函数内部还需加上注释语句来说明你的工作。
目的是使成员函数更易理解、维护和增强。
内部注释应采用两种方式:
C语言风格的注释(/*和*/)和单行注释(//)。
正如上述所讨论的,应认真考虑给代码的业务逻辑采用一种风格的注释,给要注释掉的无用代码采用另外一种风格的注释。
建议对业务逻辑采用单行注释,因为它可用于整行注释和行末注释。
采用C语言风格的注释语句去掉无用的代码,因为这样仅用一个语句就可以容易地去掉几行代码。
此外,因为C语言风格的注释语句很象文档注释符。
它们之间的用法易混淆,这样会使代码的可理解性降低。
所以,应尽量减少使用它们。
在函数内,一定要说明:
1.控制结构。
说明每个控制结构,例如比较语句和循环。
你无须读完整个控制结构内的代码才判断它的功能,而仅需看看紧靠它之前的一到两行注释即可。
2.代码做了些什么以及为什么这样做。
通常你常能看懂一段代码做了什么,但对于那些不明显的代码,你很少能判断出它为什么要那样做。
例如,看完一行代码,你很容易地就可以断定它是在定单总额上打了5%的折扣。
这很容易。
不容易的是为什么要打这个折扣。
显然,肯定有一条商业法则说应打折扣,那么在代码中至少应该提到那条商业法则,这样才能使其他开发者理解你的代码为什么会是这样。
3.局部变量。
虽然我们在第4章将仔细讨论这一点,在一个成员函数内定义的每一个局部变量都应在它代码的所在行声明,并且应采用一个行内注释说明它的用法。
4.难或复杂的代码。
若发现不能或者没有时间重写代码,那么应将成员函数中的复杂代码详细地注释出来。
一般性的经验法则是,如果代码并非显而易见的,则应说明。
5.处理顺序。
如果代码中有的语句必须在一个特定的顺序下执行,则应保证将这一点注释出来[AMB98]。
没有比下面更糟糕的事了:
你对一段代码做一点简单的改动,却发现它不工作,于是花了几个小时查找问题,最后发现原来是搞错了代码的执行顺序。
在闭括号后加上注释。
常常会发现你的控制结构内套了一个控制结构,而在这个控制结构内还套了一个控制结构。
虽然应该尽量避免写出这样的代码,但有时你发现最好还是要这样写。
问题是闭括号}应该属于哪一个控制结构这一点就变得混淆了。
一个好消息是,有一些编辑器支持一种特性:
当选用了一个开括号后,它会自动地使相应得闭括号高亮显示;一个坏消息是,并非所有的编辑器都支持这种属性。
我发现通过将类似//endif,//endfor,//endswitch,&这样的注释加在闭括号所在行的行后,可以使代码更易理解。
编写清晰整洁的代码的技巧
这一部分讲述几个技巧,这些技巧有助于区分专业软件开发者和蹩脚代码编写者。
这些技巧是:
∙给代码加上注释
∙给代码分段
∙使用空白
∙遵循30秒条规则
∙说明消息发送的顺序
∙写短小单独的命令行
给代码加上注释
记住:
如果你的代码不值得注释,那么它就不值得保留[NAG95]。
当正确地使用了本文提到的注释标准和方针,就可以大幅度地提高代码质量。
让代码分段/缩进
一种提高代码可读性的方法是给代码分段,换句话说,就是在代码块内让代码缩进。
所有在括号{和}之内的代码,构成一个块。
基本思想是,块内的代码都应统一地缩进去一个单位。
Java的约定似乎是开括号放在块的所有者所在行的后面,闭括号应缩进一级。
在[LAF97]指出的很重要的一点是,你所在的机构应选取一个缩进风格并始终使用这种风格。
采用与你的Java开发环境所生成的代码一样的缩进风格。
在代码中使用空白。
在Java代码中加入几个空行,也叫空白,将代码分为一些小的、容易理解的部分,可以使它更加可读。
[VIS96]建议采用一个空行来分隔代码的逻辑组,例如控制结构,采用两个空行来分隔成员函数定义。
没有空白的代码很难读,很难理解。
遵循30秒条法则
其他的程序员应能在少于30秒钟的时间内完全理解你的成员函数,理解它做什么,为什么这样做,它是怎样做的。
如果他们做不到,说明你的代码太难维护,应加以改进。
30秒钟,明明白白。
一个好的经验法则是:
如果一个成员函数一个屏幕装不下,那么它就很可能太长了。
写短小单独的命令行
每一行代码只做一件事情。
在依赖于穿孔卡片的计算机发展的早期,想让一行代码完成尽量多的功能的想法是可以理解的。
若想在一行里做多件事情,就会使代码难于理解。
为什么要这样呢?
我们应使代码尽量容易理解,从而更容易维护和改进。
正如同一个成员函数应该并且只能做一件事一样,一行代码也只应做一件事情。
此外,应让代码在一个屏幕内可见[VIS96]。
也不应向右滚动编辑窗口来读取一整行代码,包括含有行内注释语句的代码。
说明运行顺序
提高代码可读性的一个相当简单的方法是使用圆括号(parenthesis,又叫“roundbrackets”)来说明Java代码运行的准确顺序[NAG95];[AM
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 编程 标准 规范