手册下载链接:https://pan.baidu.com/s/1kNYcboI-KwDuTbuW086YwQ 提取码:3271
1、命名风格
代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束
代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式
类名使用 UpperCamelCase 风格,但以下情形例外:DO / BO / DTO / VO / AO / PO / UID等
方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式
常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长(eg:CACHE_EXPIRED_TIME)
抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类以类名开头,以 Test 结尾
类型与中括号紧挨相连来表示数组
POJO 类中布尔类型变量都不要加 is 前缀,否则部分框架解析会引起序列化错误
包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词
包名统一使 用单数形式,但是类名如果有复数含义,类名可以使用复数形式
避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可读性降低
杜绝完全不规范的缩写,避免望文不知义
对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用 Impl 的后缀与接口区别
数据对象:xxxDO,xxx 即为数据表名
数据传输对象:xxxDTO,xxx 为业务领域相关的名称
展示对象:xxxVO,xxx 一般为网页名称
POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO
2、常量定义
不允许任何魔法值(即未经预先定义的常量)直接出现在代码中
在 long 或者 Long 赋值时,数值后使用大写的 L,不能是小写的 l,小写容易跟数字1混淆,造成误解
常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、 包内共享常量、类内共享常量
跨应用共享常量:放置在二方库中,通常是 client.jar 中的constant 目录下
应用内共享常量:放置在一方库中,通常是子模块中的constant 目录下
子工程内部共享常量:即在当前子工程的 constant 目录下
包内共享常量:即在当前包下单独的 constant 目录下
类内共享常量:直接在类内部 private static final 定义
3、代码格式
如果是大括号内为空,则简洁地写成{}即可,大括号中间无需换行和空格
如果是非空代码块则:左大括号前不换行后换行,右大括号前换行后还有 else 等代码则不换行;表示终止的右大括号后必须换行
左右小括号和字符之间都不出现空格,而左大括号前需要空格
if/ for/ while/ switch/ do 等保留字与括号之间都必须加空格
任何二目、三目运算符的左右两边都需要加一个空格
采用4个空格缩进,禁止使用 tab 字符
注释的双斜线与注释内容之间有且仅有一个空格
在进行类型强制转换时,右括号与强制转换值之间不需要任何空格隔开
单行字符数限制不超过 120 个,超出需要换行
方法参数在定义和传入时,多个参数逗号后边必须加空格
IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式,不 要使用 Windows 格式
4、OOP规约
避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可
所有的覆写方法,必须加@Override 注解
相同参数类型,相同业务含义,才可以使用 Java 的可变参数,避免使用 Object
外部正在调用或者二方库依赖的接口,不允许修改方法签名,避免对接口调用方产生影响
接口过时必须加 @Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么
不能使用过时的类或方法
Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals
所有整型包装类对象之间值的比较,全部使用 equals 方法比较
浮点数之间的等值判断,基本数据类型不能用 == 来比较,包装数据类型不能用 equals 来判断
定义数据对象 DO 类时,属性类型要与数据库字段类型相匹配
为了防止精度损失,禁止使用构造方法 BigDecimal(double) 的方式把 double 值转化为 BigDecimal 对象
所有的 POJO 类属性必须使用包装数据类型,RPC 方法的返回值和参数必须使用包装数据类型
定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值
序列化类新增属性时,请不要修改 serialVersionUID 字段,避免反序列失败
如果完全不兼容升级,避免反序列化混乱,那么请修改 serialVersionUID 值
构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中
POJO 类必须写 toString 方法
使用 IDE 中的工具:source> generate toString 时,如果继承了另一个 POJO 类,注意在前面加一下 super.toString
禁止在 POJO 类中,同时存在对应属性 xxx 的 isXxx() 和 getXxx() 方法
循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展
5、控制语句
在一个 switch 块内,每个 case 要么通过 continue/break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止
在一个 switch 块内,都必须包含一个 default 语句并且放在最后,即使它什么代码也没有
当 switch 括号内的变量类型为 String 并且此变量为外部参数时,必须先进行 null 判断
在 if/ else/ for/ while/ do 语句中必须使用大括号
在高并发场景中,避免使用”等于”判断作为中断或退出的条件
6、注释规约
类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 // xxx 方式
所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释
除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能
所有的类都必须添加创建者和创建日期
方法内部单行注释,在被注释语句上方另起一行,使用 // 注释;方法内部多行注释使用 /* */ 注释,注意与代码对齐
所有的枚举类型字段必须要有注释,说明每个数据项的用途
7、MySQL数据库
表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint(1 表示是,0 表示否)
表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字
数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑
表名不使用复数名词,禁用保留字
主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名
小数类型为 decimal,禁止使用 float 和 double
如果存储的字符串长度几乎相等,使用 char 定长字符串类型
varchar 是可变长字符串,不预先分配存储空间,长度不要超过5000
如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率
表必备三字段:id,create_time,update_time
业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引
超过三个表禁止 join。需要 join 的字段,数据类型必须绝对一致
多表关联查询时,保证被关联的字段需要有索引
在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可
页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决
不要使用 count(列名) 或 count(常量) 来替代 count(*)
count(*) 是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关
count(distinct col) 计算该列除NULL之外的不重复行数
注意 count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0
当某一列的值全是NULL时,count(col) 的返回结果为0,但 sum(col) 的返回结果为NULL,因此使用 sum() 时需注意NPE问题
使用 ISNULL() 来判断是否为 NULL 值
代码中写分页查询逻辑时,若 count 为0应直接返回,避免执行后面的分页语句
不得使用外键与级联,一切外键概念必须在应用层解决
禁止使用存储过程,存储过程难以调试和扩展,更没有移植性
数据订正(特别是删除、修改记录操作)时,要先 select,避免出现误删除,确认无误才能执行更新语句
在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明
POJO 类的布尔属性不能加 is,而数据库字段必须加 is_,要求在 resultMap 中进行字段与属性之间的映射
不要用 resultClass 当返回参数,即使所有类属性名与数据库字段一一对应,也需要定义
反过来,每一个表也必然有一个 POJO 类与之对应
sql.xml 配置参数使用:#{},#param# 不要使用 ${} 此种方式容易出现 SQL 注入
iBATIS 自带的 queryForList(String statementName,int start,int size) 不推荐使用
不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出
更新数据表记录时,必须同时更新记录对应的 gmt_modified 字段值为当前时间
8、其它
在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度
velocity 调用 POJO 类的属性时,直接使用属性名取值即可,模板引擎会自动按规范调用 POJO 的 getXxx()
如果是 boolean 基本数据类型变量(boolean 命名不需要加 is 前缀),会自动调用 isXxx()方法
后台输送给页面的变量必须加$!{var}——中间的感叹号
注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够取到零值,注意除零异常)
如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法
获取当前毫秒数 System.currentTimeMillis(); 而不是 new Date().getTime();