Hewlett-PackardCompanyJavaCodingGuidelinesfor
HPGM-AS
GDAS
Preparedby:GDASSEPG
DocumentRevisionHistory
Ver.No. Ver.Date PreparedBy ReviewedBy ApprovedBy AffectedSection&SummaryofChange PIFNo. 1.0 Mar-09,2004 Gopinath HPpractitioners ShamimAhmed InitialBaseline 1.1 July-10,2004 Rennick SEPG EricPais FormatupdatedtobeinlinewithHPGlobalMethod 1.2 Apr07,2006 Vadiraj SEPG EricPais IntegratedJavacodingguidelinesdocumentsentwiththisPIFbydoingthegapanalysis. 1022 1.3 Jan,25th2007. JavaSMEs SEPG EricPais Updatedinlinewithpractitioner’sinputs. 1360 1.4 August–24-2007 Veeresh SEPG EricPais Contentincoverpage/supdatedtoexcluderedundantinformation. 1873,1417,1667 1.5 June2,2009 Wj.Lin
TableofContents
1 介绍 4
1.1 为什么要有编码规范? 4
2 文件 4
2.1 文件后缀 4
2.2 常用文件名(CommonFileNames) 5
3 文件组织(FileOrganization) 5
3.1 Java源文件(JavaSourceFiles) 5
3.5.1 开头注释(BeginningComments) 5
3.5.2 包和引入语句(PackageandImportStatements) 6
3.5.3 类和接口声明(ClassandInterfaceDeclarations) 6
4 缩进排版(Indentation) 6
4.1 行长度(LineLength) 6
4.2 换行(WrappingLines) 6
5 注释(Comments) 8
5.1 实现注释的格式(ImplementationCommentFormats) 8
5.5.1 块注释(BlockComments) 8
5.5.2 单行注释(Single-LineComments) 9
5.5.3 尾端注释(TrailingComments) 9
5.5.4 行末注释(End-Of-LineComments) 10
5.2 文档注释(DocumentationComments) 10
6 声明(Declarations) 10
6.1 每行声明变量的数量(NumberPerLine) 10
6.2 初始化(Initialization) 11
6.3 布局(Placement) 11
6.4 类和接口的声明(ClassandInterfaceDeclarations) 11
7 语句(Statements) 12
7.1 简单语句(SimpleStatements) 12
7.2 复合语句(CompoundStatements) 12
7.3 返回语句(returnStatements) 12
7.4 if,if-else,ifelse-ifelse语句(if,if-else,ifelse-ifelseStatements) 12
7.5 for语句(forStatements) 13
7.6 while语句(whileStatements) 14
7.7 do-while语句(do-whileStatements) 14
7.8 switch语句(switchStatements) 14
7.9 try-catch语句(try-catchStatements) 15
8 空白 15
8.1 空行(BlankLines) 15
8.2 空格(BlankSpaces) 16
9 命名规范(NamingConventions) 16
10 编程惯例(ProgrammingPractices) 17
10.1 提供对实例以及类变量的访问控制(ProvidingAccesstoInstanceandClassVariables) 17
10.2 引用类变量和类方法(ReferringtoClassVariablesandMethods) 17
10.3 常量(Constants) 17
10.4 变量赋值(VariableAssignments) 17
10.5 其它惯例(MiscellaneousPractices) 18
10.5.1 圆括号(Parentheses) 18
10.5.2 返回值(ReturningValues) 18
10.5.3 条件运算符"?"前的表达式(Expressionsbefore''?''intheConditionalOperator) 18
10.5.4 特殊注释(SpecialComments) 19
11 代码范例(CodeExamples) 19
11.1 Java源文件范例(JavaSourceFileExample) 19
介绍
为什么要有编码规范?
编码规范对于程序员而言尤为重要,有以下几个原因:
一个软件的生命周期中,80%的花费在于维护。
几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护。
编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码。
如果你将源码作为产品发布,就需要确任它是否被很好的打包并且清晰无误,一如你已构建的其它任何产品。
为了方便工作,每个软件开发人员必须一致遵守编码规范。
下面是一些开发人员可以遵守的java代码的约定。
文件
文件后缀(FileSuffixes)
Java程序使用下列文件后缀:
文件类别 文件后缀 Java源文件 java Java字节码文件 .class
常用文件名(CommonFileNames)
常用的文件名包括:
文件名 用途 GNUmakefile makefiles的首选文件名。 README 概述特定目录下所含内容的文件的首选文件名
文件组织(FileOrganization)
一个文件由被空行分割而成的段落以及标识每个段落的可选注释共同组成。
超过2000行的程序难以阅读,应该尽量避免。"Java源文件范例"提供了一个布局合理的Java程序范例。
Java源文件(JavaSourceFiles)
开头注释(参见"开头注释")
包和引入语句(参见"包和引入语句")
类和接口声明(参见"类和接口声明")
开头注释(BeginningComments)
/
Thisclassrepresentsasampletodemonstratehowtoprovide
class-levelcomments
Versioninformation
Date
Copyrightnotice
/
包和引入语句(PackageandImportStatements)
在多数Java源文件中,第一个非注释行是包语句。在它之后可以跟引入语句。例如:
packagejava.awt;
importjava.awt.peer.CanvasPeer;
/addedadditonalcontent/
类和接口声明(ClassandInterfaceDeclarations)
下表描述了类和接口声明的各个部分以及它们出现的先后次序。
参见一个包含注释的例子:
类/接口声明的各部分 注解 类/接口文档注释(/……/) 类或接口的声明 该注释应包含任何有关整个类或接口的信息,而这些信息又不适合作为类/接口文档注释。 类的(静态)变量 首先是类的公共变量,随后是保护变量,再后是包一级别的变量(没有访问修饰符,accessmodifier),最后是私有变量。 实例变量 构造器
方法
缩进排版(Indentation)
行长度(LineLength)
注意:用于文档中的例子应该使用更短的行长,长度一般不超过70个字符。
换行(WrappingLines)
在一个逗号后面断开
在一个操作符前面断开
宁可选择较高级别(higher-level)的断开,而非较低级别(lower-level)的断开
新的一行应该与上一行同一级别表达式的开头处对齐
如果以上规则导致你的代码混乱或者使你的代码都堆挤在右边,那就代之以缩进8个空格
以下是断开方法调用的一些例子:
someMethod(longExpression1,longExpression2,longExpression3,
longExpression4,longExpression5);
var=someMethod1(longExpression1,
someMethod2(longExpression2,
longExpression3));
以下是两个断开算术表达式的例子。前者更好,因为断开处位于括号表达式的外边,这是个较高级别的断开:
longName1=longName2(longName3+longName4-longName5)
+4longname6;//PREFER
longName1=longName2(longName3+longName4
-longName5)+4longname6;//AVOID
以下是两个缩进方法声明的例子。前者是常规情形。后者若使用常规的缩进方式将会使第二行和第三行移得很靠右,所以代之以缩进8个空格
//CONVENTIONALINDENTATION
someMethod(intanArg,ObjectanotherArg,StringyetAnotherArg,
ObjectandStillAnother){
...
}
//INDENT8SPACESTOAVOIDVERYDEEPINDENTS
privatestaticsynchronizedhorkingLongMethodName(intanArg,
ObjectanotherArg,StringyetAnotherArg,
ObjectandStillAnother){
...
}
if语句的换行通常使用8个空格的规则,因为常规缩进(4个空格)会使语句体看起来比较费劲:
//DON''TUSETHISINDENTATION
if((condition1&&condition2)
||(condition3&&condition4)
||!(condition5&&condition6)){//BADWRAPS
doSomethingAboutIt(); //MAKETHISLINEEASYTOMISS
}
//USETHISINDENTATIONINSTEAD
if((condition1&&condition2)
||(condition3&&condition4)
||!(condition5&&condition6)){
doSomethingAboutIt();
}
//ORUSETHIS
if((condition1&&condition2)||(condition3&&condition4)
||!(condition5&&condition6)){
doSomethingAboutIt();
}
这里有三种可行的方法用于处理三元运算表达式:
alpha=(aLongBooleanExpression)?beta:gamma;
alpha=(aLongBooleanExpression)?beta
:gamma;
alpha=(aLongBooleanExpression)
?beta
:gamma;
注释(Comments)
Java程序有两类注释:实现注释(implementationcomments)和文档注释(documentcomments)。实现注释是那些在C++中见过的,使用/.../和//界定的注释。文档注释(被称为"doccomments")是Java独有的,并由/.../界定。文档注释可以通过javadoc工具转换成HTML文件。
实现注释用以注释代码或者实现细节。文档注释从实现自由(implementation-free)的角度描述代码的规范。它可以被那些手头没有源码的开发人员读懂。
注释应被用来给出代码的总括,并提供代码自身没有提供的附加信息。注释应该仅包含与阅读和理解程序有关的信息。例如,相应的包如何被建立或位于哪个目录下之类的信息不应包括在注释中。
在注释里,对设计决策中重要的或者不是显而易见的地方进行说明是可以的,但应避免提供代码中己清晰表达出来的重复信息。多余的的注释很容易过时。通常应避免那些代码更新就可能过时的注释
注意:频繁的注释有时反映出代码的低质量。当你觉得被迫要加注释的时候,考虑一下重写代码使其更清晰。
注释不应写在用星号或其他字符画出来的大框里。
注释不应包括诸如制表符和回退符之类的特殊字符。
实现注释的格式(ImplementationCommentFormats)
程序可以有4种实现注释的风格:块(block)、单行(single-line)、尾端(trailing)和行末(end-of-line)。
块注释(BlockComments)
块注释之首应该有一个空行,用于把块注释和代码分割开来,比如:
/
Hereisablockcomment.
/
块注释可以以/-开头,这样indent(1)就可以将之识别为一个代码块的开始,而不会重排它。比如:
/-
Hereisablockcommentwithsomeveryspecial
FormattingthatIwantindent(1)toignore.
One
Two
Three
/
注意:如果你不使用indent(1),就不必在代码中使用/-,或为他人可能对你的代码运行indent(1)作让步。
单行注释(Single-LineComments)
短注释可以显示在一行内,并与其后的代码具有一样的缩进层级。如果一个注释不能在一行内写完,就该采用块注释(参见"块注释")。单行注释之前应该有一个空行。以下是一个Java代码中单行注释的例子:
if(condition){
/Handlethecondition./
...
}
尾端注释(TrailingComments)
极短的注释可以与它们所要描述的代码位于同一行,但是应该有足够的空白来分开代码和注释。若有多个短注释出现于大段代码中,它们应该具有相同的缩进。
以下是一个Java代码中尾端注释的例子:
if(a==2){
returnTRUE;/specialcase/
}else{
returnisPrime(a);/worksonlyforodda/
}
行末注释(End-Of-LineComments)
注释界定符"//",可以注释掉整行或者一行中的一部分。它一般不用于连续多行的注释文本;然而,它可以用来注释掉连续多行的代码段。以下是所有三种风格的例子:
if(foo>1){
//Doadouble-flip.
...
}
else{
returnfalse;//Explainwhyhere.
}
//if(bar>1){
//
////Doatriple-flip.
//...
//}
//else{
//returnfalse;
//}
文档注释(DocumentationComments)
/
TheExampleclassprovides...
/
publicclassExample{...
注意顶层(top-level)的类和接口是不缩进的,而其成员是缩进的。描述类和接口的文档注释的第一行(/)不需缩进;随后的文档注释每行都缩进1格(使星号纵向对齐)。成员,包括构造函数在内,其文档注释的第一行缩进4格,随后每行都缩进5格。
若你想给出有关类、接口、变量或方法的信息,而这些信息又不适合写在文档中,则可使用实现块注释(见5.1.1)或紧跟在声明后面的单行注释(见5.1.2)。例如,有关一个类实现的细节,应放入紧跟在类声明后面的实现块注释中,而不是放在文档注释中。
文档注释不能放在一个方法或构造器的定义块中,因为Java会将位于文档注释之后的第一个声明与其相关联。
声明(Declarations)
每行声明变量的数量(NumberPerLine)
intlevel;//indentationlevel
intsize;//sizeoftable
要优于:
intlevel,size;
不要将不同类型变量的声明放在同一行,例如:
intfoo,fooarray[];//WRONG!
注意:上面的例子中,在类型和标识符之间放了一个空格,另一种被允许的替代方式是使用制表符:
int level; //indentationlevel
int size; //sizeoftable
Object currentEntry; //currentlyselectedtableentry
初始化(Initialization)
尽量在声明局部变量的同时初始化。唯一不这么做的理由是变量的初始值依赖于某些先前发生的计算。
布局(Placement)
voidmyMethod(){
intint1=0;//beginningofmethodblock
if(condition){
intint2=0;//beginningof"if"block
...
}
}
该规则的一个例外是for循环的索引变量
for(inti=0;i
避免声明的局部变量覆盖上一级声明的变量。例如,不要在内部代码块中声明相同的变量名:
intcount;
...
myMethod(){
if(condition){
intcount=0;//AVOID!
...
}
...
}
类和接口的声明(ClassandInterfaceDeclarations)
当编写类和接口是,应该遵守以下格式规则:
在方法名与其参数列表之前的左括号"("间不要有空格
左大括号"{"位于声明语句同行的末尾
右大括号"}"另起一行,与相应的声明语句对齐,除非是一个空语句,"}"应紧跟在"{"之后
classSampleextendsObject{
intivar1;
intivar2;
Sample(inti,intj){
ivar1=i;
ivar2=j;
}
intemptyMethod(){}
...
}
方法与方法之间以空行分隔
语句(Statements)
argv++; //Correct
argc--; //Correct
argv++;argc--; //AVOID!
复合语句(CompoundStatements)
复合语句是包含在大括号中的语句序列,形如"{语句}"。例如下面各段。
被括其中的语句应该较之复合语句缩进一个层次
左大括号"{"应位于复合语句起始行的行尾;右大括号"}"应另起一行并与复合语句首行对齐
大括号可以被用于所有语句,包括单个语句,只要这些语句是诸如if-else或for控制结构的一部分。这样便于添加语句而无需担心由于忘了加括号而引入bug
返回语句(returnStatements)
return;
returnmyDisk.size();
return(size?size:defaultSize);
if,if-else,ifelse-ifelse语句(if,if-else,ifelse-ifelseStatements)
if语句应该具有如下格式:
if(condition1){
abc=100;
xyz=200;
}
if(condition1){
//Asinglelineisalsoenclosedwithinflowerbraces
abc=100;
}
if-else语句应该具有如下格式:
if(condition1){
abc=100;
xyz=200;
}else{
abc=300;
xyz=400;
}
if(condition1){
abc=100;
xyz=200;
}elseif(condition2){
abc=300;
xyz=400;
if(condition2){
abc=800;
}else{
xyz=800;
}
}else{
abc=500;
xyz=600;
}
注意:if语句总是用"{"和"}"括起来,避免使用如下容易引起错误的格式:
if(condition)//AVOID!THISOMITSTHEBRACES{}!
statement;
for语句(forStatements)
一个for语句应该具有如下格式:
for(initialization;condition;expression){
statement1;
statement2;
:
}
for(initialization;
condition;
expression){
statement1;
statement2;
:
}
一个空的for语句(所有工作都在初始化,条件判断,更新子句中完成)应该具有如下格式:
for(initialization;condition;update);
当在for语句的初始化或更新子句中使用逗号时,避免因使用三个以上变量,而导致复杂度提高。若需要,可以在for循环之前(为初始化子句)或for循环末尾(为更新子句)使用单独的语句。
while语句(whileStatements)
一个while语句应该具有如下格式:
while(condition){
statement1;
statement2;
:
}
一个空的while语句应该具有如下格式:
while(condition);
do-while语句(do-whileStatements)
一个do-while语句应该具有如下格式:
do{
statement1;
statement2;
:
}while(condition);
switch语句(switchStatements)
一个switch语句应该具有如下格式:
switch(condition){
caseabc:
statement1;
statement2;
break;
casexyz:
statement1;
statement2;
break;
/Thedefaultcaseshouldalwaysbepresenteven
ifitisemptyandshouldbeendedwithabreak
statement
/
default:
statement1;
statement2;
break;
}
每当一个case顺着往下执行时(因为没有break语句),通常应在break语句的位置添加注释。上面的示例代码中就包含注释/fallsthrough/。
try-catch语句(try-catchStatements)
一个try-catch语句应该具有如下格式:
try{
statements;
}catch(ExceptionClasse){
statements;
}
一个try-catch语句后面也可能跟着一个finally语句,不论try代码块是否顺利执行完,它都会被执行。
try{
abc=Integer.parseInt(“abc”);
:
:
}catch(NumberFormatExceptionnfe){
:
:
}catch(IOExceptionioe){
:
:
}finally{
:
:
}
/AddednewsectionforSynchronizationusage/
空白
空行将逻辑相关的代码段分隔开,以提高可读性。
下列情况应该总是使用两个空行:
一个源文件的两个片段(section)之间
类声明和接口声明之间
下列情况应该总是使用一个空行:
两个方法之间
方法内的局部变量和方法的第一条语句之间
一个方法内的两个逻辑段之间,用以提高可读性
空格(BlankSpaces)
一个紧跟着括号的关键字应该被空格分开,例如:
while(true){
...
}
注意:空格不应该置于方法名与其左括号之间。这将有助于区分关键字和方法调用。
空白应该位于参数列表中逗号的后面
所有的二元运算符,除了".",应该使用空格将之与操作数分开。一元操作符和操作数之间不因该加空格,比如:负号("-")、自增("++")和自减("--")。例如:
a+=c+d;
a=(a+b)/(cd);
while(d++=s++){
n++;
}
printSize("sizeis"+foo+"\n");
for语句中的表达式应该被空格分开,例如:
for(expr1;expr2;expr3)
强制转型后应该跟一个空格,例如:
myMethod((byte)aNum,(Object)x);
myMethod((int)(cp+5),((int)(i+3))
命名规范(NamingConventions)
标识符类型 命名规则 例子
包(Packages) com.sun.eng
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
类(Classes) 命名规则:类名是个一名词,采用大小写混合的方式,每个单词的首字母大写。尽量使你的类名简洁而富于描述。使用完整单词,避免缩写词(除非该缩写词被更广泛使用,像URL,HTML) classImageSprite;
classraster; 接口(Interfaces) 命名规则:大小写规则与类名相似 interfaceRasterDelegate;interfaceStoring; 方法(Methods) run();runFast();getBackground();
变量(Variables) Inti;
charc;
floatmyWidth; 常量(Constants) StaticfinalintMIN_WIDTH=4;
staticfinalintMAX_WIDTH=999;
staticfinalintGET_THE_CPU=1; 编程惯例(ProgrammingPractices)
提供对实例以及类变量的访问控制(ProvidingAccesstoInstanceandClassVariables)
一个具有公有实例变量的恰当例子,是类仅作为数据结构,没有行为。亦即,若你要使用一个结构(struct)而非一个类(如果java支持结构的话),那么把类的实例变量声明为公有是合适的。
引用类变量和类方法(ReferringtoClassVariablesandMethods)
classMethod(); //OK
AClass.classMethod(); //OK
anObject.classMethod(); //AVOID!
常量(Constants)
位于for循环中作为计数器值的数字常量,除了-1,0和1之外,不应被直接写入代码。
变量赋值(VariableAssignments)
fooBar.fChar=barFoo.lchar=''c'';//AVOID!
不要将赋值运算符用在容易与相等关系运算符混淆的地方。例如:
if(c++=d++){//AVOID!(Javadisallows)
...
}
应该写成
if((c++=d++)!=0){
...
}
不要使用内嵌(embedded)赋值运算符试图提高运行时的效率,这是编译器的工作。例如:
d=(a=b+c)+r;//AVOID!
应该写成
a=b+c;
d=a+r;
其它惯例(MiscellaneousPractices)
圆括号(Parentheses)
一般而言,在含有多种运算符的表达式中使用圆括号来避免运算符优先级问题,是个好方法。即使运算符的优先级对你而言可能很清楚,但对其他人未必如此。你不能假设别的程序员和你一样清楚运算符的优先级。
if(a==b&&c==d)//AVOID!
if((a==b)&&(c==d))//RIGHT
返回值(ReturningValues)
设法让你的程序结构符合目的。例如:
if(booleanExpression){
returntrue;
}else{
returnfalse;
}
应该代之以如下方法:
returnbooleanExpression;
类似地:
if(condition){
returnx;
}
returny;
应该写做:
return(condition?x:y);
条件运算符"?"前的表达式(Expressionsbefore''?''intheConditionalOperator)
如果一个包含二元运算符的表达式出现在三元运算符"?:"的"?"之前,那么应该给表达式添上一对圆括号。
例如:
(x>=0)?x:-x;
特殊注释(SpecialComments)
在注释中使用XXX来标识某些未实现(bogus)的但可以工作(works)的内容。用FIXME来标识某些假的和错误的内容。
代码范例(CodeExamples)
Java源文件范例(JavaSourceFileExample)
下面的例子,展示了如何合理布局一个包含单一公共类的Java源程序。接口的布局与其相似。更多信息参见"类和接口声明"以及"文挡注释"。
/
@(#)Blah.java1.8299/03/18
Copyright(c)1994-1999SunMicrosystems,Inc.
901SanAntonioRoad,PaloAlto,California,94303,U.S.A.
Allrightsreserved.
ThissoftwareistheconfidentialandproprietaryinformationofSun
Microsystems,Inc.("ConfidentialInformation").Youshallnot
disclosesuchConfidentialInformationandshalluseitonlyin
accordancewiththetermsofthelicenseagreementyouenteredinto
withSun.
/
packagejava.blah;
importjava.blah.blahdy.BlahBlah;
/
Classdescriptiongoeshere.
@version 1.8218Mar1999
@author FirstnameLastname
/
publicclassBlahextendsSomeClass{
/Aclassimplementationcommentcangohere./
/classVar1documentationcomment/
publicstaticintclassVar1;
/
classVar2documentationcommentthathappenstobe
morethanonelinelong
/
privatestaticObjectclassVar2;
/instanceVar1documentationcomment/
publicObjectinstanceVar1;
/instanceVar2documentationcomment/
protectedintinstanceVar2;
/instanceVar3documentationcomment/
privateObject[]instanceVar3;
/
...constructorBlahdocumentationcomment...
/
publicBlah(){
//...implementationgoeshere...
}
/
...methoddoSomethingdocumentationcomment...
/
publicvoiddoSomething(){
//...implementationgoeshere...
}
/
...methoddoSomethingElsedocumentationcomment...
@paramsomeParamdescription
/
publicvoiddoSomethingElse(ObjectsomeParam){
//...implementationgoeshere...
}
}
HPGM-AS JavaCodingGuidelines GDAS
HPGlobalMethod HPRestricted Page2of20 Guidelines(Version1.4/30-August-2007)
AS_ENG3003G ?Copyright2009Hewlett-PackardDevelopmentCompany,L.P.
Validagreementrequired. AS_ENG3003GJava.docLastchanged:02June2009at16:21
|
|