|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
令人可喜的是java现在已经开源了,所以我想我上述的想法也许有一天会实现,因为java一直都是不断创新的语言,每次创新都会给我们惊喜,这也是我喜欢java的一个原因。编码|标准1先容(Introduction)
1.1为何要有编码标准
编码标准关于程序员而言尤其主要,有以下几个缘故原由:
-一个软件的性命周期中,80%的消费在于保护
-几近没有任何一个软件,在其全部性命周期中,均由最后的开辟职员来保护
-编码标准能够改良软件的可读性,可让程序员尽快而完全地舆解新的代码
-假如你将源码作为产物公布,就必要确任它是不是被很好的打包而且明晰无误,一如你已构建的别的任何产物
为了实行标准,每一个软件开辟职员必需分歧恪守编码标准。
1.2版权声明
本文档反应的是SunMicroSystems公司,Java言语标准中的编码尺度部分。次要奉献者包含:PeterKing,PatrickNaughton,MikeDeMoney,JonniKanerva,KathyWalrath和ScottHommel。
本文档现由ScottHommel保护,有关批评定见请发至shommel@eng.sun.com
2.文件名
这部排列出了经常使用的文件名及厥后缀。
2.1文件后缀
Java程序利用以下文件后缀
文件种别文件后缀
Java源文件.java
Java字节码文件.class
2.2经常使用文件名
Java程序利用以下文件后缀
文件种别文件后缀
Java源文件.java
Java字节码文件.class
3.文件构造
一个文件由被空行支解而成的段落和标识每一个段落的可选正文配合构成。凌驾2000行的程序难以浏览,应当只管制止。"Java源文件典范"供应了一个结构公道的Java程序典范。
3.1jAVA源文件
每一个Java源文件都包括一个单一的大众类或接口。若公有类和接口与一个大众类相干联,能够将它们和大众类放进统一个源文件。大众类必需是这个文件中的第一个类或接口。
Java源文件还遵守以下划定规矩:
-开首正文(拜见"开首正文")
-包和引进语句(拜见"包和引进语句")
-类和接口声明(拜见"类和接口声明")
3.1.1开首正文
一切的源文件都应当在开首有一个C言语作风的正文,个中列出类名、版本信息、日期和版权声明:
/*
*Classname
*
*Versioninformation
*
*Date
*
*Copyrightnotice
*/
3.1.2包和引进语句
在多半Java源文件中,第一个非正文行是包语句。在它以后能够跟引进语句。比方:
packagejava.awt;
importjava.awt.peer.CanvasPeer;
3.1.3类和接口申明
下表形貌了类和接口声明的各个部分和它们呈现的前后序次。拜见"Java源文件典范"中一个包括正文的例子。
类/接口声明的各部分注解
1类/接口文档正文(/**……*/)该正文中所需包括的信息,拜见"文档正文"
2类或接口的声明
3类/接话柄现的正文(/*……*/)假如有需要的话该正文应包括任何有关全部类或接口的信息,而这些信息又不合适作为类/接口文档正文。
4类的(静态)变量起首是类的大众变量,随后是回护变量,再后是包一级其余变量(没有会见润色符,accessmodifier),最初是公有变量。
5实例变量起首是大众级其余,随后是回护级其余,再后是包一级其余(没有会见润色符),最初是公有级其余。
6机关器
7办法这些办法应当按功效,而非感化域或会见权限,分组。比方,一个公有的类办法能够置于两个私有的实例办法之间。其目标是为了更便于浏览和了解代码。
4.缩进排版
4个空格常被作为缩进排版的一个单元。缩进切实其实切注释并未具体指定(空格vs.制表符)。一个制表符即是8个空格(而非4个)。
4.1行长度
只管制止一行的长度凌驾80个字符,由于良多终端和工具不克不及很优点理之。
注重:用于文档中的例子应当利用更短的行长,长度一样平常不凌驾70个字符。
4.2换行
当一个表达式没法包容在一行内时,能够根据以下一样平常划定规矩断开之:
-在一个逗号前面断开
-在一个操纵符后面断开
-宁肯选择较初级别(higher-level)的断开,而非较初级别(lower-level)的断开
-新的一行应当与上一行统一级别表达式的开首处对齐
-假如以上划定规矩招致你的代码凌乱大概使你的代码都堆挤在右侧,那就代之以缩进8个空格。
以下是断开办法挪用的一些例子:
someMethod(longExpression1,longExpression2,longExpression3,
longExpression4,longExpression5);
var=someMethod1(longExpression1,
someMethod2(longExpression2,
longExpression3));
以下是两个断开算术表达式的例子。前者更好,由于断开处位于括号表达式的外边,这是个较初级其余断开。
longName1=longName2*(longName3+longName4-longName5)
+4*longname6;//PREFFER
longName1=longName2*(longName3+longName4
-longName5)+4*longname6;//AVOID
以下是两个缩进办法声明的例子。前者是惯例情况。后者若利用惯例的缩进体例将会使第二行和第三行移得很靠右,以是代之以缩进8个空格
//CONVENTIONALINDENTATION
someMethod(intanArg,ObjectanotherArg,StringyetAnotherArg,
ObjectandStillAnother){
...
}
//INDENT8SPACESTOAVOIDVERYDEEPINDENTS
privatestaticsynchronizedhorkingLongMethodName(intanArg,
ObjectanotherArg,StringyetAnotherArg,
ObjectandStillAnother){
...
}
if语句的换行一般利用8个空格的划定规矩,由于惯例缩进(4个空格)会使语句体看起来对照费力。好比:
//DONTUSETHISINDENTATION
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;
5.正文
Java程序有两类正文:完成正文(implementationcomments)和文档正文(documentcomments)。完成正文是那些在C++中见过的,利用/*...*/和//界定的正文。文档正文(被称为"doccomments")是Java独占的,并由/**...*/界定。文档正文能够经由过程javadoc工具转换成HTML文件。
完成正文用以正文代码大概完成细节。文档正文从完成自在(implementation-free)的角度形貌代码的标准。它能够被那些手头没有源码的开辟职员读懂。
正文应被用来给出代码的总括,并供应代码本身没有供应的附加信息。正文应当仅包括与浏览和了解程序有关的信息。比方,响应的包怎样被创建或位于哪一个目次下之类的信息不该包含在正文中。
在正文里,对计划决议中主要的大概不是不言而喻的中央举行申明是能够的,但应制止供应代码中己明晰表达出来的反复信息。过剩的的正文很简单过期。一般应制止那些代码更新便可能过期的正文。
注重:频仍的正文偶然反应出代码的低质量。当你以为自愿要加正文的时分,思索一下重写代码使其更明晰。
正文不该写在用星号或其他字符画出来的年夜框里。正文不该包含诸如制表符和回退符之类的特别字符。
5.1完成正文的格局
程序能够有4种完成正文的作风:块(block)、单行(single-line)、尾端(trailing)和行末(end-of-line)。
5.1.1块正文
块正文一般用于供应对文件,办法,数据布局和算法的形貌。块正文被置于每一个文件的入手下手处和每一个办法之前。它们也能够被用于其他中央,好比办法外部。在功效和办法外部的块正文应当和它们所形貌的代码具有一样的缩进格局。
块正文之首应当有一个空行,用于把块正文和代码支解开来,好比:
/*
*Hereisablockcomment.
*/
块正文能够以/*-开首,如许indent(1)就能够将之辨认为一个代码块的入手下手,而不会重排它。
/*-
*Hereisablockcommentwithsomeveryspecial
*formattingthatIwantindent(1)toignore.
*
*one
*two
*three
*/
注重:假如你不利用indent(1),就不用在代码中利用/*-,或为别人大概对你的代码运转indent(1)作妥协。
拜见"文档正文"
5.1.2单行正文
短正文能够显现在一行内,并与厥后的代码具有一样的缩进层级。假如一个正文不克不及在一行内写完,就该接纳块正文(拜见"块正文")。单行正文之前应当有一个空行。以下是一个Java代码中单行正文的例子:
if(condition){
/*Handlethecondition.*/
...
}
5.1.3尾端正文
极短的正文能够与它们所要形貌的代码位于统一行,可是应当有充足的空缺来分隔代码和正文。如有多个短正文呈现于年夜段代码中,它们应当具有不异的缩进。
以下是一个Java代码中尾端正文的例子:
if(a==2){
returnTRUE;/*specialcase*/
}else{
returnisPrime(a);/*worksonlyforodda*/
}
5.1.4行末正文
正文界定符"//",能够正文失落整行大概一行中的一部分。它一样平常不必于一连多行的正文文本;但是,它能够用来正文失落一连多行的代码段。以下是一切三种作风的例子:
if(foo>1){
//Doadouble-flip.
...
}
else{
returnfalse;//Explainwhyhere.
}
//if(bar>1){
//
////Doatriple-flip.
//...
//}
//else{
//returnfalse;
//}
5.2文档正文
注重:此处形貌的正文格局之典范,拜见"Java源文件典范"
若想懂得更多,拜见"HowtoWriteDocCommentsforJavadoc",个中包括了有关文档正文标志的信息(@return,@param,@see):
http://java.sun.com/javadoc/writingdoccomments/index.html
若想懂得更多有关文档正文和javadoc的具体材料,拜见javadoc的主页:
http://java.sun.com/javadoc/index.html
文档正文形貌Java的类、接口、机关器,办法,和字段(field)。每一个文档正文城市被置于正文定界符/**...*/当中,一个正文对应一个类、接口或成员。该正文应位于声明之前:
/**
*TheExampleclassprovides...
*/
publicclassExample{...
注重顶层(top-level)的类和接口是不缩进的,而其成员是缩进的。形貌类和接口的文档正文的第一行(/**)不需缩进;随后的文档正文每行都缩进1格(使星号纵向对齐)。成员,包含机关函数在内,其文档正文的第一行缩进4格,随后每行都缩进5格。
若你想给出有关类、接口、变量或办法的信息,而这些信息又不合适写在文档中,则可以使用完成块正文(见5.1.1)或紧跟在声明前面的单行正文(见5.1.2)。比方,有关一个类完成的细节,应放进紧跟在类声明前面的完成块正文中,而不是放在文档正文中。
文档正文不克不及放在一个办法或机关器的界说块中,由于Java会将位于文档正文以后的第一个声明与其相干联。
6声明
6.1每行声明变量的数目
保举一行一个声明,由于如许以利于写正文。亦即,
intlevel;//indentationlevel
intsize;//sizeoftable
要优于,
intlevel,size;
不要将分歧范例变量的声明放在统一行,比方:
intfoo,fooarray[];//WRONG!
注重:下面的例子中,在范例和标识符之间放了一个空格,另外一种被同意的替换体例是利用制表符:
intlevel;//indentationlevel
intsize;//sizeoftable
ObjectcurrentEntry;//currentlyselectedtableentry
6.2初始化
只管在声明部分变量的同时初始化。独一不这么做的来由是变量的初始值依附于某些先前产生的盘算。
6.3结构
只在代码块的入手下手处声明变量。(一个块是指任何被包括在年夜括号"{"和"}"两头的代码。)不要在初次用到该变量时才声明之。这会把注重力不会合的程序员弄懵懂,同时会妨害代码在该感化域内的可移植性。
voidmyMethod(){
intint1=0;//beginningofmethodblock
if(condition){
intint2=0;//beginningof"if"block
...
}
}
该划定规矩的一个破例是for轮回的索引变量
for(inti=0;i<maxLoops;i++){...}
制止声明的部分变量掩盖上一级声明的变量。比方,不要在外部代码块中声明不异的变量名:
intcount;
...
myMethod(){
if(condition){
intcount=0;//AVOID!
...
}
...
}
6.4类和接口的声明
当编写类和接口是,应当恪守以下格局划定规矩:
-在办法名与其参数列表之前的左括号"("间不要有空格
-左年夜括号"{"位于声明语句偕行的开端
-右年夜括号"}"另起一行,与响应的声明语句对齐,除非是一个空语句,"}"应紧跟在"{"以后
classSampleextendsObject{
intivar1;
intivar2;
Sample(inti,intj){
ivar1=i;
ivar2=j;
}
intemptyMethod(){}
...
}
-办法与办法之间以空行分开
7语句
7.1复杂语句
每行最多包括一条语句,比方:
argv++;//Correct
argc--;//Correct
argv++;argc--;//AVOID!
7.2复合语句
复合语句是包括在年夜括号中的语句序列,形如"{语句}"。比方上面各段。
-被括个中的语句应当较之复合语句缩进一个条理
-左年夜括号"{"应位于复合语句肇端行的行尾;右年夜括号"}"应另起一行并与复合语句首行对齐。
-年夜括号能够被用于一切语句,包含单个语句,只需这些语句是诸如if-else或for把持布局的一部分。如许便于增加语句而无需忧虑因为忘了加括号而引进bug。
7.3前往语句
一个带前往值的return语句不利用小括号"()",除非它们以某种体例使前往值更加显见。比方:
return;
returnmyDisk.size();
return(size?size:defaultSize);
7.4if,if-else,ifelse-ifelse语句
if-else语句应当具有以下格局:
if(condition){
statements;
}
if(condition){
statements;
}else{
statements;
}
if(condition){
statements;
}elseif(condition){
statements;
}else{
statements;
}
注重:if语句老是用"{"和"}"括起来,制止利用以下简单引发毛病的格局:
if(condition)//AVOID!THISOMITSTHEBRACES{}!
statement;
7.5for语句
一个for语句应当具有以下格局:
for(initialization;condition;update){
statements;
}
一个空的for语句(一切事情都在初始化,前提判别,更新子句中完成)应当具有以下格局:
for(initialization;condition;update);
当在for语句的初始化或更新子句中利用逗号时,制止因利用三个以上变量,而招致庞大度进步。若必要,能够在for轮回之前(为初始化子句)或for轮回开端(为更新子句)利用独自的语句。
7.6while语句
一个while语句应当具有以下格局
while(condition){
statements;
}
一个空的while语句应当具有以下格局:
while(condition);
7.7do-while语句
一个do-while语句应当具有以下格局:
do{
statements;
}while(condition);
7.8switch语句
一个switch语句应当具有以下格局:
switch(condition){
caseABC:
statements;
/*fallsthrough*/
caseDEF:
statements;
break;
caseXYZ:
statements;
break;
default:
statements;
break;
}
每当一个case顺着往下实行时(由于没有break语句),一般应在break语句的地位增加正文。下面的示例代码中就包括正文/*fallsthrough*/。
7.9try-catch语句
一个try-catch语句应当具有以下格局:
try{
statements;
}catch(ExceptionClasse){
statements;
}
一个try-catch语句前面也大概随着一个finally语句,不管try代码块是不是顺遂实行完,它城市被实行。
try{
statements;
}catch(ExceptionClasse){
statements;
}finally{
statements;
}
8空缺
8.1空行
空即将逻辑相干的代码段分开开,以进步可读性。
以下情形应当老是利用两个空行:
-一个源文件的两个片断(section)之间
-类声明和接口声明之间
以下情形应当老是利用一个空行:
-两个办法之间
-办法内的部分变量和办法的第一条语句之间
-块正文(拜见"5.1.1")或单行正文(拜见"5.1.2")之前
-一个办法内的两个逻辑段之间,用以进步可读性
8.2空格
以下情形应当利用空格:
-一个紧随着括号的关头字应当被空格分隔,比方:
while(true){
...
}
注重:空格不该该置于办法名与其左括号之间。这将有助于辨别关头字和办法挪用。
-空缺应当位于参数列表中逗号的前面
-一切的二元运算符,除".",应当利用空格将之与操纵数分隔。一元操纵符和操纵数之间不因该加空格,好比:负号("-")、自增("++")和自减("--")。比方:
a+=c+d;
a=(a+b)/(c*d);
while(d++=s++){
n++;
}
printSize("sizeis"+foo+"
");
-for语句中的表达式应当被空格分隔,比方:
for(expr1;expr2;expr3)
-强迫转型后应当跟一个空格,比方:
myMethod((byte)aNum,(Object)x);
myMethod((int)(cp+5),((int)(i+3))+1);
9定名标准
定名标准使程序更容易读,从而更容易于了解。它们也能够供应一些有关标识符功效的信息,以助于了解代码,比方,不管它是一个常量,包,仍是类。
标识符范例定名划定规矩例子
包(Packages)一个独一包名的前缀老是全体小写的ASCII字母而且是一个顶级域名,一般是com,edu,gov,mil,net,org,或1981年ISO3166尺度所指定的标识国度的英文双字符代码。包名的后续部分依据分歧机构各自外部的定名标准而不尽不异。这类定名标准大概以特定目次名的构成来辨别部门(department),项目(project),呆板(machine),或注册名(loginnames)。com.sun.eng
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
类(Classes)定名划定规矩:类名是个一位词,接纳巨细写夹杂的体例,每一个单词的首字母年夜写。只管使你的类名简便而富于形貌。利用完全单词,制止缩写词(除非该缩写词被更普遍利用,像URL,HTML)classRaster;
classImageSprite;
接口(Interfaces)定名划定规矩:巨细写划定规矩与类名类似interfaceRasterDelegate;
interfaceStoring;
办法(Methods)办法名是一个动词,接纳巨细写夹杂的体例,第一个单词的首字母小写,厥后单词的首字母年夜写。run();
runFast();
getBackground();
变量(Variables)除变量名外,一切实例,包含类,类常量,均接纳巨细写夹杂的体例,第一个单词的首字母小写,厥后单词的首字母年夜写。变量名不该以下划线或美圆标记开首,只管这在语法上是同意的。
变量名应冗长且富于形貌。变量名的选用应当易于影象,即,可以指出其用处。只管制止单个字符的变量名,除非是一次性的一时变量。一时变量一般被取名为i,j,k,m和n,它们一样平常用于整型;c,d,e,它们一样平常用于字符型。charc;
inti;
floatmyWidth;
实例变量(InstanceVariables)巨细写划定规矩和变量名类似,除后面必要一个下划线int_employeeId;
String_name;
Customer_customer;
常量(Constants)类常量和ANSI常量的声明,应当全体年夜写,单词间用下划线离隔。(只管制止ANSI常量,简单引发毛病)staticfinalintMIN_WIDTH=4;
staticfinalintMAX_WIDTH=999;
staticfinalintGET_THE_CPU=1;
10编程常规
10.1供应对实例和类变量的会见把持
若没有充足来由,不要把实例或类变量声明为私有。一般,实例变量无需显式的设置(set)和猎取(gotten),一般这作为办法挪用的边沿效应(sideeffect)而发生。
一个具有私有实例变量的得当例子,是类仅作为数据布局,没有举动。亦即,若你要利用一个布局(struct)而非一个类(假如java撑持布局的话),那末把类的实例变量声明为私有是符合的。
10.2援用类变量和类办法
制止用一个对象会见一个类的静态变量和办法。应当用类名替换。比方:
classMethod();//OK
AClass.classMethod();//OK
anObject.classMethod();//AVOID!
10.3常量
位于for轮回中作为计数器值的数字常量,除-1,0和1以外,不该被间接写进代码。
10.4变量赋值
制止在一个语句中给多个变量赋不异的值。它很难读懂。比方:
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;
10.5别的常规
10.5.1圆括号
一样平常而言,在含有多种运算符的表达式中利用圆括号来制止运算符优先级成绩,是个好办法。即便运算符的优先级对你而言大概很分明,但对其别人一定云云。你不克不及假定其余程序员和你一样分明运算符的优先级。
if(a==b&&c==d)//AVOID!
if((a==b)&&(c==d))//RIGHT
10.5.2前往值
想法让你的程序布局切合目标。比方:
if(booleanExpression){
returntrue;
}else{
returnfalse;
}
应当代之以以下办法:
returnbooleanExpression;
相似地:
if(condition){
returnx;
}
returny;
应当写做:
return(condition?x:y);
10.5.3前提运算符"?"前的表达式
假如一个包括二元运算符的表达式呈现在三元运算符"?:"的"?"之前,那末应当给表达式添上一对圆括号。比方:
(x>=0)?x:-x;
10.5.4特别正文
在正文中利用XXX来标识某些未完成(bogus)的但能够事情(works)的内容。用FIXME来标识某些假的和毛病的内容
11代码典范
11.1Java源文件典范
上面的例子,展现了怎样公道结构一个包括单一大众类的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.
*
*@version1.8218Mar1999
*@authorFirstnameLastname
*/
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...
}
}
诸如RMI,EJB等一些技术并不是你说的那么复杂,而是它们把一些复杂的工具封装成不复杂的工具了,理解这些工具是需要些时间。我问你,.net里有这些工具吗?要简单多少?。 |
|