daily 2017 7 24 常用编码规范 - wtdig/study GitHub Wiki

编码规范

1、需要使用构造函数时,首先考虑能否使用静态工厂替代

2、判断语句,if里面的代码块为正常情况下的代码、else为不正常的代码

3、接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 javadoc注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础 常量。

4、枚举类名建议带上Enum后缀,枚举成员名称需要全大写,单词间用下划线隔开。

5、各层命名规约: A) Service/DAO层方法命名规约 1) 获取单个对象的方法用get做前缀。 2) 获取多个对象的方法用list做前缀。 3) 获取统计值的方法用count做前缀。 4) 插入的方法总是用save(推荐)或insert做前缀。 5) 删除的方法总是用remove(推荐)或delete做前缀。 6) 修改的方法总是用update做前缀。 B) 领域模型命名规约 1) 数据对象:xxxDO,xxx即为数据表名。 2) 数据传输对象:xxxDTO,xxx为业务领域相关的名称。 3) 展示对象:xxxVO,xxx一般为网页名称。 4) POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。

6、对外暴露的接口签名,原则上不允许修改方法签名,避免对接口调用方产生影响。接口过时必须加 @Deprecated注解,并清晰地说明采用的新接口或者新服务是什么。

7、所有的相同类型包装类对象之间值的比较,全部使用equals方法比较。 说明:对于Integer var=?在128 至127之间的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这 个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有 对象,这是一个大坑,推荐使用equals方法进行判断。

8、关于基本数据类型与包装数据类型的使用标准如下: 1) 所有的POJO类属性使用包装数据类型。 2) RPC方法的返回值和参数必须使用包装数据类型。 3) 所有的局部变量使用基本数据类型。 说明:POJO类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何NPE问题,或者入库检 查,都由使用者来保证。 正例:数据库的查询结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险。 反例:某业务的交易报表上显示成交总额涨跌情况,即正负x%,x为基本数据类型,调用的HSF服务,调用不成功 时,返回的是默认值,页面显示:0%,这是不合理的,应该显示成中划线 。所以包装数据类型的null值,能够表示 额外的信息,如:远程调用失败,异常退出。

9、序列化类修改时,请不要修改serialVersionUID字段,避免反序列失败;如果完全不兼容升级,避免反序列 化混乱,那么请修改serialVersionUID值。 说明:注意serialVersionUID不一致会抛出序列化运行时异常。

10、POJO类必须写toString方法。使用工具类source> generate toString时,如果继承了另一个POJO类,注意 在前面加一下super.toString。 说明:在方法执行抛出异常时,可以直接调用POJO的toString()方法打印其属性值,便于排查问题。

11、循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展

12、final可提高程序响应效率,声明成final的情况: 1) 不需要重新赋值的变量,包括类属性、局部变量。 2) 对象参数前加final,表示不允许修改引用的指向。 3) 类方法确定不允许被重写。

13、Map/Set的key为自定义对象时,必须重写hashCode和equals。 说明:为什么要重写hashCode() (http://blog.csdn.net/sweetanan888/article/details/8543537)。 正例:String重写了hashCode和equals方法,所以我们可以非常愉快地使用String对象作为key来使用。

14、使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方 法会抛出UnsupportedOperationException异常。 说明:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只 是转换接口,后台的数据仍是数组。 String[] str = new String[] { "a", "b" }; List list = Arrays.asList(str); 第一种情况:list.add("c"); 运行时异常。 第二种情况:str[0]= "gujin"; 那么list.get(0)也会随之修改。

15、不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对 Iterator对象加锁。

16、高度注意Map类集合K/V能不能存储null值的情况,如下表格: 集合类Key Value Super 说明 Hashtable 不允许为null 不允许为null Dictionary 线程安全 ConcurrentHashMap 不允许为null 不允许为null AbstractMap 线程局部安全 TreeMap 不允许为null 允许为null AbstractMap 线程不安全 HashMap 允许为null 允许为null AbstractMap 线程不安全 反例:前期抽样表明近八成的同学认为ConcurrentHashMap是可以置入null值。在“美杜莎 (http://mcmsportal. alibabainc. com/?from=faq)”的批量翻译场景中,子线程分发时,出现置入null值的情况,但主线程没有捕获到 此异常,导致排查困难。

17、循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行 不必要的trycatch 操作(这个trycatch 是否可以移至循环体外)。

18、有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回滚事务

19、防止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。 反例:“一拍档客户”的返回值从空对象变成了null,导致线上故障,NPE无小事。

20、小数类型为decimal,禁止使用float和double。 说明:float和double在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数 据范围超过decimal的范围,建议将数据拆成整数和小数分开存储。

⚠️ **GitHub.com Fallback** ⚠️