(一)改掉这些坏习惯,还怕写不出健壮的代码?

Code Review 是一场苦涩但有意思的修行 。
近期对团队负责的项目 , 进行了一次 Code Review , 代码评审过程中遇到的那些编码坏习惯 , 笑的合不拢嘴 。 不过 , 评审中很多代码编写问题 , 以往都多次提及过 , 所以气还是不打一处来 。
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
作为用代码编写人生的程序员 , 能拥有写一手健壮代码的本领 , 那绝对很有必要 。 因为健壮的代码能够把 Bug 扼杀在摇篮里 , 能够让问题止步于上线前 。
那么 , 怎样才能练就写出健壮代码的本领呢?
本次着重谈谈那些代码编写时的一些坏习惯 , 改掉这些坏习惯 , 相信会向健壮代码迈进一大步 。
编码时易忽略性能的坏习惯 坏习惯一:调用低效的构造器 , 创建包装类型的对象 。
反例:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
正解:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
解惑:使用 Long.valueOf(long) 代替 new Long(long) , 可以提高性能 。
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
如 Long 源码所示 , 如果当传入的值介于 -128~127 时 , 会优先从缓存中返回缓存的值 , 而不是进行 new , 充分利用空间换取时间 , 所以当值介于 -128~127 时 , 采取 Long.valueOf(long) 的效率要比 new Long(long) 快很多 。
建议:
a)凡是涉及到 Long, Integer, Short, Character 以及 Byte 创建对象时 , 优先采用高效的 valueOf() 方法 , 而不是直接用低效构造器创建实例 。
b)享元设计模式在这儿用到了 , 什么是享元模式?(留个作业)
坏习惯二:使用 keySet 迭代器迭代 Map , 获取对应的 value 。
反例:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
正解:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
解惑:keySet 方式遍历 Map 的性能不如 entrySet 性能好 。
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
如果采用 keySet 的方式获取 Map 中 key , 然后通过 key 获取 Map 对应的 value , 如上图 HashMap 源码所示 , 每次都需要通过 key 去计算对应的 hash 值 , 然后再通过 hash 值获取对应的 value , 效率会低不少 。
建议:
a)如果想获取 Map 对应的 key 和 value , 则推荐使用 entrySet 。
【(一)改掉这些坏习惯,还怕写不出健壮的代码?】b)如果只是单纯获取 Map 对应的 key , 则推荐使用 keySet 。
坏习惯三:使用 new Date().getTime() 获取当前时间戳 。
反例:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
正解:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
解惑:如下图 Date 源码所示 , Date 构造方法中最终还是调用了 System.currentTimeMillis() 方法来获取时间戳 。
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
建议:
a)获取当前毫秒数采用 System.currentTimeMillis() , 而不是new Date().getTime();
b)获取更加精确的纳秒级时间值 , 采用 System.nanoTime;
c)在 JDK8 中 , 针对统计时间等场景 , 建议使用 Instant 类 。
坏习惯四:循环中使用 ”+“ 号拼接字符串 。
反例:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
正解:推荐使用 StringBuilder/StringBuffer 进行字符串拼接 。
解惑:「Java 程序该怎么优化?技巧篇」以前的这篇分享做过试验 , 本次不赘述 。
编码时易犯的一些小毛病 毛病一:变量作为 equals() 方法的调用方 。
反例:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
正解:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
解惑:totalCount 应该作为方法 equals() 的调用方 , 而不是参数 作为调用方 , 因为参数作为调用方会出现空指针异常 。
建议:
a)字符串的比较 , 常量建议当做 equals() 方法的调用方;
b)字符串判断空 , 建议用项目中的工具类 。
毛病二:对象为 null 的检查滞后 。
反例1:
(一)改掉这些坏习惯,还怕写不出健壮的代码?文章插图
正解:请在使用 data 对象前 , 做好是否为 null 的判断 。