好的代码格式犹如一篇优美的文章,阅读时令人心旷神怡。
注释风格
- 【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 //xxx 方式。
说明 : 在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE 中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高 阅读效率。 - 【强制】所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
说明 : 对子类的实现要求,或者调用注意事项,请一并说明。 - 【强制】所有的类都必须添加创建者和创建日期。
- 【强制】方法内部单行注释,在被注释语句上方另起一行,使用 //注释。方法内部多行注释使用/* */注释,注意与代码对齐。
- 【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途。
- 【推荐】与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持英文原文即可。
反例 : “TCP 连接超时”解释成“传输控制协议连接超时”,理解反而费脑筋。 - 【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。
说明 : 代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后, 就失去了导航的意义。 - 【参考】合理处理注释掉的代码。在上方详细说明,而不是简单的注释掉。如果无用,则删除。
说明 : 代码被注释掉有两种可能性: 1)后续会恢复此段代码逻辑。2)永久不用。前者如果没 有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。 - 【参考】对于注释的要求: 第一、能够准确反应设计思想和代码逻辑;第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。
- 【参考】好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的一个极端: 过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。
反例 :
// put elephant into fridge
put(elephant, fridge);
方法名 put,加上两个有意义的变量名 elephant 和 fridge,已经说明了这是在干什么,语义清晰的代码不需要额外的注释。
- 【参考】特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描,经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。
-
- 待办事宜(TODO)😦 标记人,标记时间,[预计处理时间])表示需要实现,但目前还未实现的功能。这实际上是一个 Javadoc 的标签,目前的 Javadoc 还没有实现,但已经被广泛使用。只能应用于类,接口和方法(因为它是一个 Javadoc 标签)。
- 错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。
换行与空格
1、大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果是非空代码块则:
-
- 左大括号前不换行。
- 左大括号后换行。
- 右大括号前换行。
- 右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。
2、 左、右小括号和字符之间不出现空格。详见 第 5 条下方正例提示。
反例 : if (空格 a == b 空格)
正例:if(a == b)
3、 if/for/while/switch/do 等保留字与括号之间都必须加空格。
4、缩进采用 4 个空格,禁止使用 tab 字符。
说明 : 如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时,请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs。
正例 : (涉及 1-4 点)
public static void main(String[] args) {
// 缩进 4 个空格
String say = "hello";
// 运算符的左右必须有一个空格
int flag = 0;
// 关键词 if 与括号之间必须有一个空格,括号内的 f 与左括号,0 与右括号不需要空格
if (flag == 0) {
System.out.println(say);
}
// 左大括号前加空格且不换行;左大括号后换行
if (flag == 1) {
System.out.println("world");
// 右大括号前换行,右大括号后有 else,不用换行
} else {
System.out.println("ok");
// 在右大括号后直接结束,则必须换行
}
}
5、单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:
- 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
- 运算符与下文一起换行。
- 方法调用的点符号与下文一起换行。
- 在多个参数超长,在逗号后换行。
- 在括号前不要换行,见反例。
正例 :
StringBuffer sb = new StringBuffer();
//超过 120 个字符的情况下,换行缩进 4 个空格,并且方法前的点符号一起换行
sb.append("zi").append("xin")...
.append("huang")...
.append("huang")...
.append("huang");
反例 :
StringBuffer sb = new StringBuffer();
//超过 120 个字符的情况下,不要在括号前换行
sb.append("zi").append("xin")...append
("huang");
//参数很多的方法调用可能超过 120 个字符,不要在逗号前换行
method(args1, args2, args3, ...
, argsX);
- 方法参数在定义和传入时,多个参数逗号后边必须加空格。
正例 : 下例中实参的"a",后边必须要有一个空格。method("a", "b", "c"); - IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不要使用 windows 格式。
- 【推荐】没有必要增加若干空格来使某一行的字符与上一行对应位置的字符对齐。
正例 :
int a = 3;
long b = 4L;
float c = 5F;
StringBuffer sb = new StringBuffer();
说明 : 增加 sb 这个变量,如果需要对齐,则给 a、b、c 都要增加几个空格,在变量比较多的情况下,是一种累赘的事情。
- 【推荐】方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。
说明 : 没有必要插入多个空行进行隔开。
语句控制
语句控制建议
- 【强制】在一个 switch 块内,每个 case 要么通过 break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止;在一个 switch 块内,都必须包含一个 default 语句并且放在最后,即使它什么代码也没有。
- 【推荐】表达异常的分支时,少用 if-else 方式,这种方式可以改写成:
if (condition) {
...
return obj;
}
// 接着写 else 的业务逻辑代码;
说明 : 如果非得使用 if()...else if()...else...方式表达逻辑,避免后续代码维护困难,请勿超过 3 层。
正例 : 逻辑上超过 3 层的 if-else 代码可以使用卫语句,或者状态模式来实现。卫语句示例如下:
public void today() {
if (isBusy()) {
System.out.println(“change time.”);
return;
}
if (isFree()) {
System.out.println(“go to travel.”);
return;
}
System.out.println(“stay at home to learn Alibaba Java Coding Guideline.”);
return;
}
- 【推荐】除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
说明 : 很多 if 语句内的逻辑相当复杂,阅读者需要分析条件表达式的最终结果,才能明确什么样的条件执行什么样的语句,那么,如果阅读者分析逻辑表达式错误呢?
正例 :
//伪代码如下
final boolean existed = (file.open(fileName, "w") != null) && (...) || (...);
if (existed) {
...
}
反例 :
if ((file.open(fileName, "w") != null) && (...) || (...)) {
...
}
扩展
《代码大全2》第14章 组织直线型代码_代码应该自上而下阅读_@来杯咖啡的博客-CSDN博客
《代码大全2》第15章 使用条件语句_@来杯咖啡的博客-CSDN博客
《代码大全2》第16章 控制循环_@来杯咖啡的博客-CSDN博客
《代码大全2》第17章 不常见的控制结构_@来杯咖啡的博客-CSDN博客
《代码大全2》第18章 表驱动法_阶梯访问表_@来杯咖啡的博客-CSDN博客
参考资料
《阿里巴巴开发规范》
《代码大全2》