代碼優化不是過早優化,而是在性能分析定位瓶頸後的針對性改進。本文總結 13 條經過實戰驗證的 Java 性能優化策略,涵蓋異常處理、內存管理、循環優化、字符串操作、對象復用等核心領域。
原則:異常僅用於錯誤場景,不可用於正常流程控制。
原因:異常拋出需創建對象、填充堆疊追蹤(fillInStackTrace()),開銷極大。
對策:用條件判斷替代可預測的錯誤檢查(如數組越界前先判斷長度)。
Java 默認初始化字段(null/0/false),構造鏈會層層調用。
優化:在聲明處顯式初始化或構造器中一次性賦值,避免默認初始化後再賦值的雙重開銷。
final 類不可繼承,編譯器可內聯其所有方法(視編譯器實現而定)。
實測:某些場景下性能提升可達 50%。
典型案例:String、包裝類均為 final。
局部變量存棧,訪問速度快;實例/靜態變量存堆,訪問慢。
建議:方法內臨時計算結果優先用局部變量,減少堆訪問。
反例:方法參數用 File 但內部只用 InputStream。
優化:直接接受 InputStream,減少對象創建與轉換開銷,同時提高復用性。
左移 << n 等價乘以 2^n,右移 >> n 等價除以 2^n。
適用場景:高頻循環中的整數乘除 2 的冪次。
注意:降低可讀性,僅在性能熱點代碼使用,並添加註釋。
捕獲 OutOfMemoryError 並嘗試釋放緩存重試:
try {
obj = new LargeObject();
cache.put(key, obj);
} catch (OutOfMemoryError e) {
flushCache(); // 清理緩存釋放內存
obj = get(key); // 重試
}
同理可應用於連接池、線程池資源耗盡場景。
按需創建昂貴對象。
優化前:構造器預創建異常對象。
優化後:僅在拋出時創建:
if (n < 0) throw new IllegalArgumentException("must be >= 0");
多個獨立 try-catch 合併為單一 try 多 catch,便於編譯器優化:
try {
method1();
method2();
method3();
} catch (Ex1 e) { ... }
catch (Ex2 e) { ... }
catch (Ex3 e) { ... }
優化前:for (int i=0; isize()。
優化後:for (int i=0, n=list.size(); i
現代 JVM:JIT 可能自動優化,但顯式緩存無副作用且更穩健。
StringBuilder,無需手動干預。StringBuilder/StringBuffer:StringBuilder sb = new StringBuilder(estimatedSize);
for (String s : array) sb.append(s);
String result = sb.toString();
傳入可復用對象引用,避免循環內重複創建:
public Point getPosition(Point reusable) {
if (reusable == null) reusable = new Point();
reusable.x = this.x;
reusable.y = this.y;
return reusable;
}
// 調用處
Point p = new Point();
for (Component c : components) {
Point pos = c.getPosition(p); // 復用同一對象
process(pos);
}
PreparedStatement 替代 Statement,防注入+性能更優。性能優化應基於 Profiling 數據,針對熱點代碼應用上述策略。切記:可讀性與可維護性是首要原則,優化需在不破壞架構前提下進行。