代碼優化雙核心目標:執行效率與可讀性/可維護性。本文歸納 13 條高頻優化模式,涵蓋對象復用、變量作用域、流關閉、懶加載、異常處理、循環優化、靜態變量、I/O 緩衝、包裝類轉換、Map 遍歷、迭代器選型等實戰技巧。
| # | 優化點 | 核心原則 | 代碼對比 |
|---|---|---|---|
| 1 | 字符串拼接用 StringBuilder | 避免頻繁創建 String 對象,減輕 GC 壓力 | String s=""; for(...) s+=x; → StringBuilder sb=new StringBuilder(); for(...) sb.append(x); |
| 2 | 優先局部變量 | 棧分配快、自動回收,避免堆分配與 GC | 實例/靜態變量 → 方法內局部變量 |
| 3 | 及時關閉流 | 防止資源洩漏,使用 try-with-resources (JDK 7+) | try (InputStream is=...) { } |
| 4 | 懶加載 | 用到時才創建對象,減少無用分配 | 提前 new → if 判斷內 new |
| 5 | try-catch 移出循環 | 避免重複進棧/出棧開銷 | 循環內 try → 循環外 try |
| 6 | 縮小 try-catch 範圍 | 只包裹可能拋異常代碼,提升可讀性 | 大塊 try → 精準包裹風險行 |
| 7 | 循環外聲明引用 | 大循環避免創建大量引用變量 | while(i<1000){ Object o=new Object(); } → Object o=null; while(i<1000){ o=new Object(); } |
| 8 | 慎用 static | 靜態變量生命週期=類生命週期,阻礙 GC 回收 | 非必要勿 static,常量除外 |
| 9 | 杜絕無用對象/導入 | 減少類加載、初始化、GC 開銷 | IDE 自動清理未使用 import |
| 10 | 使用緩衝 I/O | BufferedXxx 大幅降低系統調用次數 | new BufferedReader(new FileReader(f)) |
| 11 | 包裝類轉字符串用 toString() | i.toString() > String.valueOf(i) > ""+i | 避免 ""+i 隱式創建 StringBuilder |
| 12 | Map 遍歷用 entrySet | 單次查找獲取 Key+Value,避免二次 get(key) | for(Entry e: map.entrySet()) 優於 for(k: map.keySet()) map.get(k) |
| 13 | 大數據用 Iterator,小數據用 forEach | Iterator 略快;forEach 可讀性強 | 根據數據量與團隊規約選型 |
String 不可變,每次 + 都產生新對象並複製字符數組。StringBuilder 內部維護可擴容字符數組,append 只擴容不複製,最終 toString() 一次性生成結果。多線程環境用 StringBuffer(同步)。
// entrySet - 推薦
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
// keySet - 避免(雙重查找)
for (String key : map.keySet()) {
String value = map.get(key); // 額外 hash 查找
}
百萬級數據下 entrySet 快 30%~50%。
remove() → Iterator(forEach 不支援)String s = ""; for(...) s += x; — O(n²) 災難new Object() — 年輕代 GC 風暴static List cache = new ArrayList() 持有大對象 — 內存洩漏static + 無狀態null 輔助 GC優化不是過早優化,而是編碼習慣。將這 13 條內化為肌肉記憶,代碼天然高效。