Effective Java Item6 避免不必要的創建物件
整理Effective Java書中Item 6: Avoid creating unnecessary objects心得筆記
主旨
如果是不可變的物件(Immutable object),重複使用該物件可以讓效能以及資源控制更好,例如之前提到的靜態工廠方法Boolean.valueOf(String)
。
點出問題
- 底層封裝了處理方式
問題在於很多開發者不知道其實自己已經不自覺創了很多物件,尤其是java開發者在現在調用api便利的情況下,也沒有去探究底層原理,積少成多造成系統壓力。下面範例判斷字符串是否為有效的羅馬數字。
看起來沒甚麼問題,使用上也正確,但卻有浪費資源問題,你也不知道自己有創建物件,而且是不斷的創建這個昂貴的對象。沿著matches原始碼往下追,最後可以找到new Pattern(regex, 0);
每次使用一次創建一次隨即就gc。
為了解決問題,將regex Pattern編譯為 Pattern 實例(它是不可變的),作為class初始化的一部分,緩存它,並在每次調用 isRomanNumeral 方法時重複使用同一個實例,這樣就不用每次都創建Pattern。這裡效能大幅提升。
2.自動裝箱封裝了處理方式
Autoboxing blurs but does not erase the distinction between primitive and boxed primitive types.
這裡也是一個非常不明顯的地方,每次執行sum += i;
都會創建Long的實例。將Long sum = 0L;
改為long sum = 0L;
可以大幅提高性能,這個是一個很容易犯的錯誤。有興趣的可以跑看看下面範例感受一下性能差距。
小結
讀完這小節可以回去看看自己過去開發的專案,馬上就可以找到不少類似的情況,慢慢修正它吧。