Code Review 是一場苦澀但有意思的修行,
近期對團隊負責的專案,進行了一次 Code Review,代碼評審程序中遇到的那些編碼壞習慣,笑的合不攏嘴,不過,評審中很多代碼撰寫問題,以往都多次提及過,所以還是按奈不住心中怒氣的小火苗,

作為用代碼撰寫人生的程式員,能擁有寫一手健壯代碼的本領,那絕對很有必要,因為健壯的代碼能夠把 Bug 扼殺在搖籃里,能夠讓問題止步于上線前,
那么,怎樣才能練就寫出健壯代碼的本領呢?
本次著重談談那些代碼撰寫時的一些壞習慣,改掉這些壞習慣,相信會向健壯代碼邁進一大步,
一、編碼時易忽略性能的壞習慣
壞習慣一:呼叫低效的構造器,創建包裝型別的物件,
反例:

正解:

解惑:使用 Long.valueOf(long) 代替 new Long(long),可以提高性能,

如 Long 原始碼所示,如果當傳入的值介于 -128~127 時,會優先從快取中回傳快取的值,而不是進行 new,充分利用空間換取時間,所以當值介于 -128~127 時,采取 Long.valueOf(long) 的效率要比 new Long(long) 快很多,
建議:
- 凡是涉及到 Long, Integer, Short, Character 以及 Byte 創建物件時,優先采用高效的 valueOf() 方法,而不是直接用低效構造器創建實體,
- 享元設計模式在這兒用到了,什么是享元模式?(留個作業)
壞習慣二:使用 keySet 迭代器迭代 Map,獲取對應的 value,
反例:

正解:

解惑:keySet 方式遍歷 Map 的性能不如 entrySet 性能好,

如果采用 keySet 的方式獲取 Map 中 key,然后通過 key 獲取 Map 對應的 value,如上圖 HashMap 原始碼所示,每次都需要通過 key 去計算對應的 hash 值,然后再通過 hash 值獲取對應的 value,效率會低不少,
建議:
- 如果想獲取 Map 對應的 key 和 value,則推薦使用 entrySet,
- 如果只是單純獲取 Map 對應的 key,則推薦使用 keySet,
壞習慣三:使用 new Date().getTime() 獲取當前時間戳,
反例:

正解:

解惑:如下圖 Date 原始碼所示,Date 構造方法中最侄訓是呼叫了 System.currentTimeMillis() 方法來獲取時間戳,

建議:
- 獲取當前毫秒數采用 System.currentTimeMillis(),而不是new Date().getTime();
- 獲取更加精確的納秒級時間值,采用 System.nanoTime;
- 在 JDK8 中,針對統計時間等場景,建議使用 Instant 類,
壞習慣四:回圈中使用 ”+“ 號拼接字串,
反例:

正解:推薦使用 StringBuilder/StringBuffer 進行字串拼接,
解惑:「Java 程式該怎么優化?技巧篇」以前的這篇分享做過試驗,本次不贅述,
二、編碼時易犯的一些小毛病
毛病一:變數作為 equals() 方法的呼叫方,
反例:

正解:

解惑:totalCount 應該作為方法 equals() 的呼叫方,而不是引數 作為呼叫方,因為引數作為呼叫方會出現空指標例外,
建議:
- 字串的比較,常量建議當做 equals() 方法的呼叫方;
- 字串判斷空,建議用專案中的工具類,
毛病二:物件為 null 的檢查滯后,
反例:

正解:請在使用 data 物件前,做好是否為 null 的判斷,
解惑:后置物件為空的檢查,可能會導致空指標例外的發生,
毛病三:要求傳入非空的方法,傳入空值,
反例:

正解:signInfo 變數的值可能存在為空的情形,導致發生空指標例外,
建議:發生例外的時候,方法該終止就終止;盡量做好防御性編程,該校驗的引數進行必要的校驗,
三、寄語寫最后
常在河邊站哪有不濕鞋,再牛逼的碼農,編碼也會有失誤的時候,很有必要借助一款代碼檢查工具,做最后一道防線,
在這里,推薦 FindBugs、Checkstyle、SonarQube 三款代碼檢查工具,不過我用的最多的當屬 FindBugs,可以拿去一試,使用門檻幾乎為零,

好了,編碼中易犯的那些臭毛病,本次就談到這里,不知道有多少條是觸動了你的心弦,希望有則改之,
關注同名公眾號:一猿小講,回復「1024」可以獲取精心為您準備的職場打怪進階資料,
一起聊技術、談業務、噴架構,少走彎路,不踩大坑,會持續輸出原創精彩分享,敬請期待!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/158282.html
標籤:Java
