codestyle.md 10.4 KB
Newer Older
1
# 代码规范
Daisyeee's avatar
Daisyeee 已提交
2 3
(以下代码规范节选于阿里巴巴Java开发手册(泰山版) )

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
##(一)命名风格
1.	【强制】代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
反 例 :_name / name / $name / name_ / name$ / name        

2.	【强制】所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,纯拼音命名方式更要避免采用。 正例:ali / alibaba / taobao / cainiao/ aliyun/ youku / hangzhou 等国际通用的名称,可视同英文。反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3


3.	【强制】类名使用 UpperCamelCase 风格,但以下情形例外:DO / BO / DTO / VO / AO / PO / UID 等。
正例:ForceCode	/	UserDO	/	HtmlDTO	/	XmlService	/	TcpUdpDeal / TaPromotion
反例:forcecode	/	UserDo	/	HTMLDto	/	XMLService	/	TCPUDPDeal / TAPromotion

4.	【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格。
正例: localValue / getHttpMessage() / inputUserId

5.	【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME
反例:MAX_COUNT / EXPIRED_TIME

6.	【强制】抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾。

7.	【强制】类型与中括号紧挨相连来表示数组。
正例:定义整形数组 int[] arrayDemo;
反例:在 main 参数中,使用 String args[]来定义。

8.	【强制】POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。
说明:在本文 MySQL 规约中的建表约定第一条,表达是与否的值采用 is_xxx 的命名方式,所以,需要在<resultMap>设置从 is_xxx 到 xxx 的映射关系。
反例:定义为基本数据类型 Boolean isDeleted 的属性,它的方法也是 isDeleted(),框架在反向解析的时候,“误以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。

9.	【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
正例:应用工具类包名为 com.alibaba.ei.kunlun.aap.util、类名为 MessageUtils(此规则参考 spring 的框架结构)

10.	【强制】避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名, 使可读性降低。
说明:子类、父类成员变量名相同,即使是 public 类型的变量也是能够通过编译,而局部变量在同一方法内的不同代码块中同名也是合法的,但是要避免使用。对于非 setter/getter 的参数名称也要避免与成员变量名称相同。

##(二)常量定义
1.	【强制】不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。
反例:
//本例中同学 A 定义了缓存的 key,然后缓存提取的同学 B 使用了 Id#taobao 来提取,少了下划线,导致故障。
String key = "Id#taobao_" + tradeId; cache.put(key, value);

2.	【强制】在 long 或者Long 赋值时,数值后使用大写的 L,不能是小写的 l,小写容易跟数字混淆,造成误解。
说明:Long a = 2l; 写的是数字的 21,还是Long 型的 2。

3.	【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。
说明:大而全的常量类,杂乱无章,使用查找功能才能定位到修改的常量,不利于理解,也不利于维护。正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。

##(三)代码格式
1.	【强制】如果是大括号内为空,则简洁地写成{}即可,大括号中间无需换行和空格;如果是非空代码块则:
1)	左大括号前不换行。
2)	左大括号后换行。
3)	右大括号前换行。
4)	表示终止的右大括号后必须换行。

2.	【强制】左小括号和右边相邻字符之间不出现空格;右小括号和左边相邻字符之间也不出现空格;而左大括号前需要加空格。详见第 5 条下方正例提示。
反例:if (空格 a == b 空格)

3.	【强制】if/for/while/switch/do 等保留字与括号之间都必须加空格。

4.	【强制】任何二目、三目运算符的左右两边都需要加一个空格。
说明:包括赋值运算符=、逻辑运算符&&、加减乘除符号等。

5.	【强制】采用 4 个空格缩进,禁止使用 tab 字符。
说明:如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置tab 为 4 个空格时,请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs。
正例: (涉及 1-5 点)
```
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 {
    System.out.println("ok");
    // 在右大括号后直接结束,则必须换行
    }
}
```
6.	【强制】注释的双斜线与注释内容之间有且仅有一个空格。
正例:
// 这是示例注释,请注意在双斜线之后有一个空格
String commentString = new String();
7.	【强制】在进行类型强制转换时,右括号与强制转换值之间不需要任何空格隔开。
正例:
long first = 1000000000000L; int second = (int)first + 2;
8.	【强制】单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:
1)	第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
2)	运算符与下文一起换行。
3)	方法调用的点符号与下文一起换行。
4)	方法调用中的多个参数需要换行时,在逗号后进行。
5)	在括号前不要换行,见反例。
正例:
```
StringBuilder sb = new StringBuilder();
// 超过 120 个字符的情况下,换行缩进 4 个空格,并且方法前的点号一起换行
sb.append("zi").append("xin")...
.append("huang")...
.append("huang")...
.append("huang");
```
反例:
```
StringBuilder sb = new StringBuilder();
// 超过 120 个字符的情况下,不要在括号前换行
sb.append("you").append("are")...append ("lucky");

// 参数很多的方法调用可能超过 120 个字符,逗号后才是换行处
method(args1, args2, args3, ...
, argsX);
```

9.	【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。
正例:下例中实参的 args1,后边必须要有一个空格。
```
method(args1, args2, args3);
```

10.	【强制】IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不要使用 Windows 格式。

11.	【推荐】单个方法的总行数不超过 80 行。
说明:除注释之外的方法签名、左右大括号、方法内代码、空行、回车及任何不可见字符的总行数不超过
80 行。
正例:代码逻辑分清红花和绿叶,个性和共性,绿叶逻辑单独出来成为额外方法,使主干代码更加清晰;共性逻辑抽取成为共性方法,便于复用和维护。
 
12.	【推荐】没有必要增加若干空格来使变量的赋值等号与上一行对应位置的等号对齐。
正例:
```
int one = 1; 
long two = 2L; 
float three = 3F;
StringBuilder sb = new StringBuilder();
```
说明:增加 sb 这个变量,如果需要对齐,则给one、two、three 都要增加几个空格,在变量比较多的情况下,是非常累赘的事情。

13.	【推荐】不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。
说明:任何情形,没有必要插入多个空行进行隔开。

##(四)注释规约

1.	【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用
// xxx 方式。
说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。
正例:
```
/**
     * 功能:读取json文件,并将json中的数据全部存到字符串jsondata中
     *
     * @param jsonfilePath      json文件的路径
     *
     * @return jsondata
     */
*/
```

2.	【强制】所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
说明:对子类的实现要求,或者调用注意事项,请一并说明。
3.	【强制】所有的类都必须添加创建者和创建日期。
说明:在设置模板时,注意 IDEA 的@author 为`${USER}`,而 eclipse 的@author 为`${user}`,大小写有区别,而日期的设置统一为 yyyy/MM/dd 的格式。
正例:
```
/**

* @author yangguanbao

* @date 2016/10/31

*/
```

4.	【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
```
// 单行注释要空格
int a;
```

5.	【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途。

6.	【推荐】与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持英文原文即可。
反例:“TCP 连接超时”解释成“传输控制协议连接超时”,理解反而费脑筋。

7.	【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。
说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后,就失去了导航的意义。

8.	【推荐】在类中删除未使用的任何字段和方法;在方法中删除未使用的任何参数声明与内部变量。