Java 性能優化是一門博大精深的學問,涉及代碼層面、JVM 參數、操作系統、硬件架構等多個維度。本文彙總 11 條經驗驗證的優化技巧,涵蓋循環優化、字符串處理、基本類型選擇、異常控制、基準測試、對象創建、I/O 模型、變量初始化、final 關鍵字、局部變量優先、位運算替代乘除等,幫助開發者寫出更高效的 Java 代碼。
核心原則:避免在循環條件判斷或循環體中重複執行昂貴操作(方法調用、屬性訪問、複雜表達式)。
for (int i = 0; i < list.size(); i++) { ... } // 每次迭代調用 size()
for (int i = 0; i < array.length; i++) { // 每次訪問 length 屬性(雖然 JIT 會優化,但習慣提取)
for (int i = 0; n = list.size(); i < n; i++) { ... } // 推薦:提取到循環外
// 優化前
for (int i = 0; i < x.length; i++) {
x[i] = x[i] / scaleA * scaleB; // 每次計算 scaleA * scaleB
}
// 優化後
double scale = scaleB / scaleA; // 提取常量計算
for (int i = 0; i < x.length; i++) {
x[i] = x[i] * scale; // 單次乘法替代乘除組合
}
+ 拼接都會創建新對象、複製字符數組,性能極差。new StringBuilder(5000) 避免擴容開銷。int、long、double 等基本類型,避免自動裝箱/拆箱開銷。Integer、Long 等)僅在泛型、集合、反射、需要 null 語義時使用。static final,編譯器編譯期常量折疊,運行期直接內聯。代價高昂:創建異常對象需捕獲棧幀快照(fillInStackTrace() native 方法),調整棧幀,GC 壓力大。
try { method1(); } catch (Exception e) { ... }
try { method2(); } catch (Exception e) { ... }
try { method3(); } catch (Exception e) { ... }
try {
method1();
method2();
method3();
} catch (Method1Exception e) { ... }
catch (Method2Exception e) { ... }
catch (Method3Exception e) { ... }
if-else 判斷用戶是否存在)。Optional、Result 對象、布爾返回值處理。實現 Cloneable 並重寫 clone() 可跳過構造函數鏈,適用於原型模式、對象池、大量相似對象創建。
// 傳統工廠
public static Credit newCredit() { return new Credit(); }
// 原型模式優化
private static final Credit PROTOTYPE = new Credit();
public static Credit newCredit() {
try { return (Credit) PROTOTYPE.clone(); }
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
}
同理,數組拷貝用 Arrays.copyOf、System.arraycopy(native 實現)遠快於手寫循環。
java.nio(Channel、Buffer、Selector),單線程可管理成千上萬連接。null、數值 0、浮點 0.0、布爾 false。bipush 0、aconst_null),增加類加載、實例化時間。final class:不可繼承,所有方法隱式 final,JIT 可激進內聯(消除方法調用開銷,啟用逃逸分析、標量替換等優化),平均提升 20%-50% 吞吐量。final method:防止被重寫,同樣利於內聯。final field:構造函數結束前寫入,之後不可變,保證線程可見性(JMM final 語義),編譯器可進行常量傳播。針對 2 的冪次乘除,位移運算極快(單 CPU 指令)。
// 優化前
int a = val * 8; // 乘以 8
int b = val / 2; // 除以 2
// 優化後
int a = val << 3; // 左移 3 位 = 乘 2^3 = 8
int b = val >> 1; // 右移 1 位 = 除 2 (算術右移保留符號位)
注意:現代 JIT 編譯器(C2)已能自動將乘除 2 的冪次優化為位移,手寫位移反而降低可讀性。僅在極度熱點路徑、經 JMH 驗證確有提升時使用,並添加註釋說明意圖。