java开发规范
接口和实现类
接口定义在类名前加I;例如:ICacheService
实现类在类名后加Impl;例如:CacheServiceImpl 实现 ICacheService 接口。
Service/DAO 层方法命名规约
1) 获取多个对象的方法用 list 做前缀
领域模型命名规约
1) 数据对象: xxxDO, xxx 即为数据表名。
2) 数据传输对象: xxxDTO, xxx 为业务领域相关的名称。
3) 展示对象: xxxVO, xxx 一般为网页名称。
4) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量
1) 跨应用共享常量:放置在二方库中,通常是 client.jar 中的 const 目录下。
2) 应用内共享常量:放置在一方库的 modules 中的 const 目录下。
反例: 易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“ 是” 的变量:
类 A 中: public static final String YES = “yes”;
类 B 中: public static final String YES = “y”;
A.YES.equals(B.YES),预期是 true,但实际返回为 false,导致产生线上问题。
3) 子工程内部共享常量:即在当前子工程的 const 目录下。
4) 包内共享常量:即在当前包下单独的 const 目录下。
5) 类内共享常量:直接在类内部 private static final 定义。
如果变量值仅在一个范围内变化用 Enum 类。如果还带有名称之外的延伸属性,必须使用 Enum 类,下面正例中的数字就是延伸信息,表示星期几。
正例:
publicEnum{ MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5),SATURDAY(6), SUNDAY(7);}
方法参数在定义和传入时,多个参数逗号后边必须加空格
对外暴露的接口签名, 原则上不允许修改方法签名,避免对接口调用方产生影响。接口过时必须加@Deprecated 注解,并清晰地说明采用的新接口或者新服务是什么
所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。
说明: 对于 Integer var=?在-128 至 127 之间的赋值, Integer 对象是在 IntegerCache.cache产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断
定义 DO/DTO/VO 等 POJO 类时,不要设定任何属性默认值
反例: 某业务的 DO 的 gmtCreate 默认值为 new Date()
循环体内,字符串的联接方式,使用 StringBuilder 的 append 方法进行扩展
不要在 foreach 循环里进行元素的 remove/add 操作。 remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁
使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。
说明: keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出 key所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是 JDK8,使用 Map.foreach 方法
并发修改同一记录时,避免更新丢失,要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据
说明: 如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于 3 次。
防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:
1) 返回类型为包装数据类型,有可能是 null,返回 int 值时注意判空。
反例: public int f(){ return Integer 对象},如果为 null,自动解箱抛 NPE。
2) 数据库的查询结果可能为 null。
3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。
4) 远程调用返回对象,一律要求进行 NPE 判断。
5) 对于 Session 中获取的数据,建议 NPE 检查,避免空指针。
6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。