《Java开发手册》是集合阿里巴巴集团技术团队的集体智慧结晶和经验总结写出来的编程规范。手册以 Java开发者为中心视角,划分为编程规约、异常日志、单元测试、安全规约、MySQL 数据库、工程结构、设计规约七个维度。
本文摘选的其中一些日常需要特别注意的地方。完整的手册可以在其 GitHub主页上下载(点击打开),同时还提供了配套的配套的 Java开发规约 IDE插件,有兴趣的小伙伴可以一起下载。
一、 编程规约
1,包名统一使用小写
(1)包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
下面是一个简单的样例:
应用工具类包名为com.alibaba.ei.kunlun.aap.util
类名为 MessageUtils(此规则参考 spring的框架结构)
(2)如果包名实在没办法有且仅有一个自然语义的英语单词,那么也必须全小写:
2,接口类中的方法和属性不要加任何修饰符号
(1)接口类中的方法和属性不要加任何修饰符号(public也不要加),保持代码的简洁性,并加上有效的 Javadoc注释。
(2)尽量不要在接口里定义变量,如果一定要定义变量,确定与接口方法相关,并且是整个应用的基础常量。
正例:
接口方法签名void commit();
接口基础常量String COMPANY = "alibaba";
反例:
接口方法定义 public abstract void f();
说明:
JDK8中接口允许有默认实现,那么这个 default方法,是对所有实现类都有价值的默认实现。
3,接口和实现类的命名规则
(1)对于 Service和 DAO类,基于 SOA的理念,暴露出来的服务一定是接口,内部的实现类用 Impl的后缀与接口区别。
接口:CacheService
实现类:CacheServiceImpl
(2)如果是形容能力的接口名称,取对应的形容词为接口名(通常是 -able 的形容词)。
接口:Translatable
实现类:AbstractTranslator
4,枚举
枚举类名带上 Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。
提示:枚举其实就是特殊的常量类,且构造方法被默认强制是私有。
// 枚举样例1
public enum ProcessStatusEnum {
SUCCESS, PARAM_EMPTY, UNKNOWN_REASON
}
// 枚举样例2
public enum ProcessStatusEnum {
SUCCESS("0000", "成功"),
PARAM_EMPTY("1001", "必选参数为空"),
UNKNOWN_REASON("9999", "未知原因成功");
private String code;
private String message;
ProcessStatusEnum(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
5,各层命名规约
(1)Service/DAO层方法命名规约:
获取单个对象的方法用 get做前缀。
获取多个对象的方法用 list做前缀,复数结尾,如:listObjects。获取统计值的方法用 count做前缀。
插入的方法用 save/insert做前缀。
删除的方法用 remove/delete做前缀。
修改的方法用 update做前缀。
(2)领域模型命名规约
数据对象:xxxDO,xxx即为数据表名。
数据传输对:xxxDTO,xxx为业务领域相关的名称。
展示对象:xxxVO,xxx一般为网页名称。
注意:POJO是 DO/DTO/BO/VO的统称,禁止命名成 xxxPOJO。
6,变量、常量定义
(1)在 long或者 Long 赋值时,数值后使用大写字母 L,不能是小写字母l,小写容易跟数字混淆,造成误解。
正例:Long a = 2L
反例:Long a = 2l
(2)不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。
说明:
大而全的常量类,杂乱无章,使用查找功能才能定位到修改的常量,不利于理解,也不利于维护。
正例:
缓存相关常量放在类 CacheConsts下
系统配置相关常量放在类 SystemConfigConsts下。
(3)常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包 内共享常量、类内共享常量。
跨应用共享常量:放置在二方库中,通常是 client.jar 中的 constant目录下。
应用内共享常量:放置在一方库中,通常是子模块中的 constant目录下。
子工程内部共享常量:即在当前子工程的 constant目录下。
包内共享常量:即在当前包下单独的 constant目录下。
类内共享常量:直接在类内部 private static final 定义。
(4)如果变量值仅在一个固定范围内变化用 enum类型来定义。
如果存在名称之外的延伸属性应使用 enum类型,下面正例中的数字就是延伸信息,表示一年中的第几个季节。
public enum SeasonEnum {
SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);
private int seq;
SeasonEnum(int seq) {
this.seq = seq;
}
public int getSeq() {
return seq;
}
}
7,采用 4 个空格缩进
(1)禁止使用 Tab字符缩进,宜采用 4 个空格缩进,原因如下:
在不同的编辑器里 Tab的长度可能会不一致,这会导致有 Tab的代码,用不同的编辑器打开时,格式可能会乱。4 个空格在不同编辑器下宽度看起来是一致的。
代码压缩时,空格会有更好的压缩率。这里面是信息量的问题,使用了 Tab的代码,仍然会有空格,比如代码注释、运算符之间的间隔等等,但使用了空格的代码,是可以没有 Tab的。Tab也是一个字符,这就决定了,用 Tab 的代码虽然不压缩的时候更小,但熵更高,因此压缩率会较差,压缩之后反而更大。
(2)如果使用 Tab缩进,必须设置 1个 Tab为 4个空格:
IDEA设置 Tab为 4个空格时,请勿勾