代码编写规范Word格式文档下载.docx
《代码编写规范Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《代码编写规范Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。
三、源码文件结构
源码文件按照先后顺序,由以下几部分组成:
1.license或者copyright声明信息。
(如果需要声明)
2.包(package)声明语句。
3.import语句。
4.类声明(每个源码文件只能有一个顶级类)。
每个部分之间应该只有一行空行作为间隔。
3.1license或者copyright的声明信息。
如果需要声明license或copyright信息,应该在文件开始时声明。
3.2包声明
包声明的行没有行长度的限制。
单行长度限制不适用于包声明。
3.3import语句
3.3.1不使用通配符import
即,不要出现类似这样的import语句:
importjava.util.*;
3.3.2没有行长度限制
import语句的行没有行长度的限制。
单行长度限制不适用于import语句所在行。
3.3.3顺序和空行
import语句应该被分为几个组,每个组之间由单行的空行隔开。
分组的顺序如下:
1.所有的静态导入为归为一组。
2.com.sinosoft(项目自带包)包的import归为一组。
3.第三方包。
每个顶级包归为一组。
第三方包之间按ASCII码排序。
例如:
android,
com,
junit,org,
sun
4.java
包归为一组。
5.javax
同一组内的import语句之间不应用空行隔开。
同一组中的import语句按ASCII码排序。
3.4类声明
3.4.1只声明一个顶级类
每个源码文件中只能有一个顶级类。
例外:
package-info.java,该文件中可没有package-info类。
3.4.2类成员顺序
类成员的顺序对代码的易读性有很大影响,但这也不存在唯一的通用法则。
不同的类可能有不同的排序方式。
重要的是,每个类都要按照一定的逻辑规律排序。
维护者应该要能解释这种排序逻辑。
比如,新的方法不能总是习惯性地添加到类的结尾,因为这样就是按时间顺序而非某种逻辑来排序的。
3.4.2.1重载方法:
不应该分开
当一个类有多个构造函数,或者多个同名成员方法时,这些函数应该写在一起,不应该被其他成员分开。
四、格式
术语说明:
块状结构(block-likeconstruct)指类、成员函数和构造函数的实现部分(大括号中间部分)。
注意,在后面的4.8.3.1节中讲到数组初始化,所有的数组初始化都可以被认为是一个块状结构(非强制)。
4.1大括号
4.1.1大括号不可省略
大括号一般用在if,
else,
for,
do和while等语句。
即使当它的实现为空或者只有一句话时,也需要使用。
4.1.2非空语句块采用K&
R风格
对于非空语句块,大括号遵循Kernighan&
Ritchie风格:
∙左大括号前不换行。
∙左大括号后换行。
∙右大括号前换行。
∙如果右大括号结束一个语句块或者函数体、构造函数体或者有命名的类体,则右大括号后换行,否则不要换行。
例如,当右大括号后面接else或者逗号时,不应该换行。
例子:
1.returnnewMyClass(){
2.@Overridepublicvoidmethod(){
3.if(condition()){
4.try{
5.someting();
6.}catch(ProblemExceptione){
7.recover();
8.}
9.}
10.}
11.};
一些例外的情况,将在4.8.1节讲枚举类型的时候讲到。
4.1.3空语句块:
可以用简洁版本
一个空的语句块,大括号可以简洁地写成{},不需要换行。
如果它是一个多块语句的一部分(if/else或try/catch/finally),即使大括号内没内容,右大括号也要换行。
1.voiddoNothing(){}
4.2语句块的缩进:
4空格
每当一个新的语句块产生,缩进就增加两个空格。
当这个语句块结束时,缩进恢复到上一层级的缩进格数。
缩进要求对整个语句块中的代码和注释都适用。
(例子可参考之前4.1.2节中的例子)。
4.3一行最多只有一句代码
每句代码的结束都需要换行。
4.4行长度限制:
80或100
不同的项目可以选择采用80个字符或者100个字符作为限制。
除了以下几个特殊情况外,其他代码内容都需要遵守这个长度限制。
这在4.5节会有详细解释。
1.按照行长度限制,无法实现地方(例如:
Javadoc中超长的URL地址,或者一个超长的JSNI方法的引用);
2.
package和import语句不受长度限制。
(见3.2、3.3节);
3.注释中的命令行指令行,将被直接复制到shell中执行的。
4.5换行
当一行代码按照其他规范都合法,只是为了避免超出行长度限制而换行时,称为长行断行。
长行断行,没有一个适合所有场景的全面、确定的规范。
但很多相同的情况,我们经常使用一些行之有效的断行方法。
将长行封装为函数,或者使用局部变量的方法,也可以解决一些超出行长度限制的情况。
并非一定要断行。
4.5.1在何处断行
断行的主要原则是:
选择在更高一级的语法逻辑的地方断行。
其他一些原则如下:
1.在一个逗号后面断开。
2.在一个操作符前面断开
(=号和foreach语句的冒号除外)。
3.在调用函数或者构造函数需要断行时,与函数名相连的左括号要在一行。
也就是在左括号之后断行。
4.5.2断行的缩进:
至少8个字符
当断行之后,在第一行之后的行,我们叫做延续行。
每一个延续行在第一行的基础上至少缩进四个字符。
当原行之后有多个延续行的情况,缩进可以大于8个字符。
如果多个延续行之间由同样的语法元素断行,它们可以采用相同的缩进。
4.6.3节介绍水平对齐中,解决了使用多个空格与之前行缩进对齐的问题。
4.6空白
4.6.1垂直空白
以下情况需使用一个空行:
1.类成员之间需要空行隔开:
字段、构造函数、方法、内部类、静态初始化语句块(staticinitializers)、实例初始化语句块(instanceinitializers)。
o例外:
连续字段之间的空白行不是必需的。
一般多个字段中间的空行,是为了对字段做逻辑上的分组。
2.在函数体内,语句的逻辑分组间使用空行。
3.类的第一个成员之前,或者最后一个成员结束之后,用空行间隔。
(可选)
4.本文档中其他部分介绍的需要空行的情况。
(例如3.3节中的import语句)
单空行时使用多行空行是允许的,但是不要求也不鼓励。
4.6.2水平空白
除了语法和规范的其他规则,词语分隔、注释和Javadoc外,水平的ASCII空格只在以下情况出现:
1.所有保留的关键字与紧接它之后的位于同一行的左括号(()之间需要用空格隔开。
(例如
if、for、catch)
2.所有保留的关键字与在它之前的右大括号(})之间需要空格隔开。
(例如else、catch)
3.在左大括号({)之前都需要空格隔开。
只有两种例外:
o@SomeAnnotation({a,b})
oString[][]x={{"
foo"
}};
4.所有的二元运算符和三元运算符的两边,都需要空格隔开。
一元操作符和操作数之间不应该加空格,比如:
负号(“-”),自增(“++”)和自减(“--”)。
例:
i++;
5.逗号、冒号、分号和右括号之后。
6.如果在一条语句后做注释,则双斜杠(//)两边都要空格。
这里可以允许多个空格,但没有必要。
7.变量声明时,变量类型和变量名之间需要用空格隔开:
List<
String>
list。
8.初始化一个数组时,大括号之间可以用空格隔开,也可以不使用。
(例如:
int[]{5,6}
和
newint[]{5,6}
都可以)
这一原则并不要求或禁止一行开始或者结束时的空格。
只针对行内部字符之间的隔开。
4.6.3水平对齐:
不做强制要求
水平对齐,是指通过添加多个空格,使本行的某一符号与上一行的某一符号上下对齐。
这种对齐是允许的,但是不会做强制要求。
以下是没有水平对齐和水平对齐的例子:
1.privateintx;
//thisisfine
2.privateColorcolor;
//thistoo
3.
4.privateintx;
//permitted,butfutureedits
5.privateColorcolor;
//mayleaveitunaligned
水平对齐能够增加代码的可读性,但是增加了未来维护代码的难度。
考虑到维护时只需要改变一行代码,之前的对齐可以不需要改动。
为了对齐,你更有可能改了一行代码,同时需要更改附近的好几行代码,而这几行代码的改动,可能又会引起一些为了保持对齐的代码改动。
这种改动,在最坏的情况下可能会导致大量的无意义的工作,即使在最好的情况下,也会影响版本历史信息,减慢代码review的速度,引起更多merge代码冲突的情况。
4.7分组括号:
建议使用
除非作者和代码审核者都认为去掉小括号也不会使代码被误解,或是去掉小括号能让代码更易于阅读,否则我们不应该去掉小括号。
我们没有理由假设读者能记住整个Java运算符优先级表。
4.8特殊结构
4.8.1枚举类型
枚举常量间用逗号隔开,换行可选。
没有方法和文档的枚举类可写成数组初始化的格式:
1.privateenumSuit{CLUBS,HEARTS,SPADES,DIAMONDS}
枚举类型也是一个类(class),因此类的其他格式要求,也适用于枚举类型。
4.8.2变量声明
4.8.2.1每次声明一个变量
不要使用组合声明。
inta,b;
4.8.2.2当需要时才声明,尽快完成初始化
局部变量不应该习惯性地放在语句块的开始处声明,而应该尽量离它第一次使用的地方最近的地方声明,以减小它们的使用范围。
局部变量应该在声明的时候就进行初始化。
如果不能在声明时初始化,也应该尽快完成初始化。
4.8.3数组
4.8.3.1数组初始化:
可写成块状结构
所有数组的初始化,都可以采用和块代码相同的格式处理。
例如以下格式都是允许的:
1.newint[]{
2.0,1,2,3
3.}
2.0,
3.1,
4.2,
5.3
6.}
2.0,1,
3.2,3
4.}
1.newint[]
2.{0,1,2,3}
4.8.3.2不能使用C风格的方式声明数组
方括号应该是变量类型的一部分,因此不应该和变量名放在一起。
应该是String[]args,而不是Stringargs[]。
4.8.4switch语句
switch语句是指在switch大括号中,包含的一组或多组语句块。
每组语句块都由一个或多个switch标签(caseFOO:
或者default:
)打头。
4.8.4.1缩进
和其他语句块一样,switch大括号之后缩进4个字符。
每个switch标签之后,新起一行,再缩进4个字符,后面跟着一条或多条语句。
在标签结束后,恢复到之前的缩进,类似大括号结束。
4.8.4.2fall-through注释
在switch语句中,每个标签对应的代码执行完后,要么通过break、continue、return或抛出异常来终止,要么通过注释说明代码将继续执行下一个标签的代码。
任何能表达这个意思的注释都可以(典型的是使用
//fallthrough)。
这个注释在最后一个标签之后不需要注释。
1.switch(input){
2.case1:
3.case2:
4.prepareOneOrTwo();
5.//fallthrough
6.case3:
7.handleOneTwoOrThree();
8.break;
9.default:
10.handleLargeNumber(input);
11.}
4.8.4.3default标签需要显式声明
每个switch语句中,都需要显式声明default标签,即使它没有任何代码。
4.8.5注解(Annotations)
注解应用到类、函数或者构造函数时,应紧接Javadoc之后。
注解独占一行。
这里换行不属于长行换行(第4.5节,长行换行),因此缩进级别不变。
1.@Override
2.@Nullable
3.publicStringgetNameIfPresent(){...}
如果注解只有一个,并且不带参数。
则它可以和类或方法名放在同一行。
1.@OverridepublicinthashCode(){...}
注解应用到字段时,也是紧接Javadoc之后。
不同的是,多个注解可以放在同一行。
1.@Partial@MockDataLoaderloader;
对于参数或者局部变量使用注解的情况,没有特定的规范。
4.8.6注释
4.8.6.1语句块的注释风格
注释的缩进与它所注释的代码缩进相同。
可以采用/*...*/进行注释,也可以用//...进行注释。
当使用
/*...*/进行多行注释时,每一行都应该以*开始,并且*应该上下对齐。
注意文字和注释符之间有一个空格(4.6.2水平空白)。
1./*
2.*Thisis//Andso/*Oryoucan
3.*okay.//isthis.*evendothis.*/
4.*/
提示:
多行注释时,如果你希望集成开发环境能自动对齐注释,你应该使用
/*...*/,//...一般不会自动对齐。
4.8.7修饰符
多个类和字段的修饰符,按
《JavaLanguageSpecification
》中介绍的先后顺序排序。
具体是:
1.publicprotectedprivateabstractstaticfinaltransientvolatilesynchronizednativestrictfp
4.8.8数字型的字面值
long类型的字面值使用大写L为后缀,永远不要使用小写l(避免和1混淆)。
3000000000L
五、命名
5.1适用于所有命名标识符的通用规范
标示符只应该使用ASCII字母、数字,字母大小写敏感。
因此所有的标示符,都应该能匹配正则表达式\w+
。
标示符不需要使用特殊的前缀或后缀,如name_,mName,s_name和kName,在Java编程风格中都不再使用。
5.2不同类型的标示符规范
5.2.1包名
包名全部用小写字母,将各单词简单地连在一起(不使用下划线)。
com.example.deepspace,不要使用com.example.deepSpace或com.example.deep_space。
5.2.2类名
类名都以UpperCamelCase风格编写。
类名一般使用名词或名词短语,例如:
Character或ImmutableList。
接口名称一般也使用名词或名词短语(如:
List),有时也可以使用形容词或形容词短语(如:
Readable)。
还没有特定的规则或行之有效的约定来命名注解类型。
测试类的命名,应该以它所测试的类的名字为开头,并在最后加上Test结尾。
HashTest
、HashIntegrationTest。
5.2.3方法名
方法名都以lowerCamelCase风格编写。
方法命名一般使用动词或者动词短语,例如:
sendMessage或stop。
在JUnit的测试方法中,可以使用下划线,用来区分逻辑组件的名字,经常使用如下的结构:
test<
MethodUnderTest>
_<
state>
testPop_emptyStack。
并不存在唯一正确的方式来命名测试方法。
5.2.4常量名
常量命名,全部使用大写字符,词与词之间用下划线隔开。
(CONSTANCE_CASE)。
常量的定义:
每个常量都是一个静态final字段,但不是所有静态final字段都是常量。
在决定一个字段是否是一个常量时,考虑它是否真的感觉像是一个常量。
例如,如果任何一个该实例的观测状态是可变的,则它几乎肯定不会是一个常量。
只是永远不打算改变对象一般是不够的,它要真的一直不变才能将它示为常量。
下面是常量和非常量的例子:
1.//Constants
2.staticfinalintNUMBER=5;
3.staticfinalImmutableList<
NAMES=ImmutableList.of("
Ed"
"
Ann"
);
4.staticfinalJoinerCOMMA_JOINER=Joiner.on('
'
//becauseJoinerisimmutable
5.staticfinalSomeMutableType[]EMPTY_ARRAY={};
6.enumSomeEnum{ENUM_CONSTANT}
7.
8.//Notconstants
9.staticStringnonFinal="
non-final"
;
10.finalStringnonStatic="
non-static"
11.staticfinalSet<
mutableCollection=newHashSet<
();
12.staticfinalImmutableSet<
SomeMutableType>
mutableElements=ImmutableSet.of(mutable);
13.staticfinalLoggerlogger=Logger.getLogger(MyClass.getName());
14.staticfinalString[]nonEmptyArray={"
these"
can"
change"
};
常量一般使用名词或者名词短语命名。
5.2.5非常量的字段名
非常量字段名以lowerCamelCase风格编写。
一般使用名词或名词短语,例如:
computedValues或index。
5.2.6参数名
参数名以lowerCamelCase风格编写。
参数应该避免用单个字符命名。
5.2.7局部变量名
局部变量名以lowerCamelCase风格编写,比起其它类型的名称,局部变量名可以有更为宽松的缩写。
但即使如此,也应该尽量避免采用单个字母进行命名的情况,除了在循环体内使用的临时变量。
即使局部变量是final、不可改变的,它也不能被认为是常量,也不应该采用常量的命名方式去命名。
5.2.8类型名
类型名有两种命名方式:
1.单独一个大写字母,有时后面再跟一个数字。
(例如,E、T、X、T2)。
2.像一般的类命名一样(见5.2.2节),再在最后接一个大写字母T。
(例如,RequestT、FooBarT)。
5.3驼峰式命名法(CamelCase)
驼峰式命名法分大驼峰式命名法(UpperCamelCase)和小驼峰式命名法(lowerCamelCase)。
有时一些短语改写成驼峰形式的时候可以有多种写法。
例如一些缩写词汇,或者一些组合词:
IPv6或者iOS等。
为了统一写法,给出如下几乎可以确定为一种的写法:
1.将字符全部转换为ASCII字符,并且移除任何单引号。
例如,"
Mü
ller'
salgorithm"
被转换为"
Muellersalgorithm"
。
2.将上一步转换的结果切分成单词。
从空格处或其它标点符号处分割开。
o注意:
一些已经是驼峰式的词语,也应该在这个时候被拆分。
(例如AdWords被拆分为adwords)。
但是例如iOS之类的词语,它其实不是一个驼峰式的词语,而是人们惯例使用的一个词语,因此不用做拆分。
3.经过上面两步后,先将所有的字母转换为小写,再把每个词语的第一个字母或除第一个单词之外的单词的第一个字母转换为大写。
4.最后,将所有词语连在一起,形成一个标示符。
词语原来的大小写规则,应该被完全忽略。
以下是一些例子:
Proseform
Correct
Incorrect
"
XMLHTTPrequest"
XmlHttpRequest
XMLHTTPRequest
newcustomerID"
newCustomerId
newCustomerID
innerstopwatch"
innerStopwatch
innerStopWatch
supportsIPv6oniOS?