OOP 规约
任何货币金额,均以最小货币单位且整型类型来进行存储。
比如说人民币的最小单位是分,那假设一个商品的价格是1元钱,那就存到数据库的 price 字段,字段类型是 int 或者 bigint,值为 100,单位是分,也就是100分。
我就在这个问题上入过坑,几年前一个系统中的价格字段用的是浮点数,单位还是元,后面在价格计算上很是麻烦,而且浮点数的计算并不是完全准确的,尤其是涉及到小数位的时候。最后还是把字段调成了 int 类型,代码上涉及到价格的地方都重构了。
所以,后来当我看到手册中的这条规约的时候,有种相见恨晚的感觉。我用了惨痛的经验才换来这个教训,如果早点看到呢,岂不是省了很多事。
浮点数之间的等值判断,基本数据类型不能用==来比较,而要规定可接受的误差范围。包装数据类型不能用 equals 来判断,而要使用 compareTo 来判断。
如上所示 BigDecimal 的等值比较应使用 compareTo()方法,而不是 equals()方法。
equals()方法会比较值和精度 (1.0 与 1.00 返回结果为 false) ,而 compareTo()则会忽略精度。
定义数据对象 DO 类时,属性类型要与数据库字段类型相匹配。
正例: 数据库字段的 bigint 必须与类属性的 Long 类型相对应。
反例: 某个案例的数据库表 id 字段定义类型 bigint unsigned,实际类对象属性为 Integer,随着 id 越来越大,超过 Integer 的表示范围而溢出成为负数。
Java中PO、DO、TO、DTO、 VO、 BO、POJO 、DAO的概念
禁止使用构造方法 BigDecimal(double) 的方式把 double 值转化为 BigDecimal 对象。
说明: BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。
如:BigDecimal g = new BigDecimal(0.1F); 实际的存储值为:0.10000000149
正例: 优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf 方法,此方法内部其实执行了 Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。
BigDecimal recommend1 = new BigDecimal(“0.1”);
BigDecimal recommend2 = BigDecimal.valueOf(0.1);
关于基本数据类型与包装数据类型的使用标准有如下三点:
1、所有的POJO类属性(成员变量)必须使用包装数据类型。
2、RPC方法的返回值和参数必须使用包装数据类型。
3、所有的局部变量使用基本数据类型。
说明: 可以考虑为我们远程 RPC 调用的方法返回值可能是包装类型,故此时我们接收时,应该优先考虑为包装类型。
集合处理
使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组。
反例: 直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现 ClassCastException 错误。
正例:
List<String> list = new ArrayList<>(2);
list.add("guan");
list