物件建立、方法呼叫、鎖競爭是 Java 效能三大殺手。結合十年實戰經驗,整理八大類與物件優化技巧,助你寫出高吞吐、低延遲的代碼。
每次 new 都會觸發建構子鏈、記憶體分配、零值初始化。實作 Cloneable 並呼叫 clone() 可跳過建構子,直接複製記憶體,速度更快。適用於頻繁建立的不可變或狀態簡單的物件(如 DTO、VO)。
區域變數存放在執行緒私有的堆疊,分配/釋放極快、無 GC 壓力;實例/靜態欄位在堆上,需 GC 管理。能用區域變數就不用欄位,特別是熱點方法中的暫存計算結果。
每次呼叫涉及壓棧、跳轉、退棧。getter/setter 雖利於封裝,但在極熱路徑(如迴圈內)可考慮直接存取 package-private 或 private 欄位,或依賴 JIT 內聯優化。原則:可讀性優先,熱點再優化。
final 類/方法:不可繼承/覆寫,JIT 可安全內聯static 方法:無動態分派,直接解析private 方法:隱含 final,同樣可內聯將工具方法、純計算方法標記為 static final,讓編譯器與 JIT 最大化優化空間。
同技巧四,明確告知 JIT 不會被覆寫,觸發內聯,消除呼叫開銷。框架(如 Spring、Hibernate)透過反射存取時不受影響。
子類引用賦值給父類變數(向上轉型)無需顯式轉型,編譯器自動處理。僅在向下轉型時需 instanceof 檢查並強轉。減少多餘的 (Parent) child 寫法。
String 不可變,每次連接產生新物件,導致大量短命物件與 GC。單執行緒用 StringBuilder,多執行緒共享用 StringBuffer 或 ThreadLocal + StringBuilder。
審視代碼中的「隱性 new」:Boolean.valueOf(true) 而非 new Boolean(true)、基本型別優於包裝類型、使用基本型別陣列(int[])替代 List<Integer> 等。每個省下的物件都減輕 GC 負擔。
| 技巧 | 關鍵點 | 適用場景 |
|---|---|---|
| 減少 new | clone、物件池、基本型別 | 高頻建立的簡單物件 |
| 區域變數 | 堆疊分配、無 GC | 方法內暫存計算 |
| 減少呼叫 | 內聯、直接存取 | 熱點迴圈、遞迴 |
| final/static/private | 消除動態分派 | 工具類、核心演算法 |
| final getter/setter | 內聯優化 | 頻繁存取的 JavaBean |
| 避免轉型 | 向上轉型免費 | 多型設計 |
| StringBuilder | 可變字串、無中間物件 | 字串拼接、日誌組裝 |
| 避免過度建立 | valueOf、基本型別、陣列 | 大量資料處理、快取 |