| # | 原則 | 關鍵點 | 工具/驗證 |
|---|---|---|---|
| 1 | 避免創建不必要的對象 | 字符串字面量、基本類型包裝器緩存、靜態工廠方法 | JProfiler、Arthas、JFR |
| 2 | 接口優於抽象類,組合優於繼承 | 多實現靈活性、避免脆弱基類、職責分離 | ArchUnit、SonarQube |
| 3 | 泛型優於原生類型,包裝類謹慎使用 | 類型安全、消除強轉、Pheap 污染防護 | 編譯器檢查、Error Prone |
| 4 | 線程安全集合優先 | ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue | JCStress、線程安全測試 |
| 5 | 枚舉代替 int 常量 | 類型安全、命名空間、可攜帶行為、單例模式最佳實現 | 編譯器強制 |
| 6 | 堅持使用 @Override | 防止簽名錯誤、重寫失效、文檔化意圖 | 編譯器強制、IDE 提示 |
| 7 | 字符串拼接用 StringBuilder | 避免循環中隱式創建 StringBuilder、字符數組複製 | JMH 基準測試 |
| 8 | 異常處理原則 | 僅異常情況用異常、標準異常優先、失敗原子性、不吞沒異常 | SpotBugs、SonarQube |
| 9 | for-each 優於傳統 for | 可讀性、消除索引越界、編譯器優化等價 | 代碼審查 |
| 10 | 方法簡短、註釋清晰、命名規範 | 單一職責、自文檔化、領域術語 | Checkstyle、ArchUnit |
| 11 | 線程安全:共享可變狀態最小化 | 不可變對象、ThreadLocal、鎖分離、java.util.concurrent | JCStress、併發測試 |
| 12 | 避免線程組 | API 缺陷、功能弱、已被線程池取代 | 代碼審查 |
| 13 | 謹慎實現序列化 | serialVersionUID、readObject 驗證、代理模式、避免敏感數據 | 序列化測試、安全掃描 |
// 反模式:每次調用創建新 String
String s = new String("literal"); // 每次 new 一個對象
// 最佳:字符串字面量(常量池複用)
String s = "literal";
// Boolean/Integer 緩存範圍
Boolean.valueOf(true); // 返回單例 TRUE/FALSE
Integer.valueOf(127); // -128~127 緩存
Integer.valueOf(200); // 新對象
進階:StringBuilder 替換循環拼接、對象池模式(線程池、連接池)、Optional 避免 null 檢查對象。
// 接口定義契約
interface PaymentProcessor {
void process(Payment payment);
}
// 多種實現,運行時注入
class AlipayProcessor implements PaymentProcessor { ... }
class WechatProcessor implements PaymentProcessor { ... }
// 組合:支付服務不繼承處理器,而是持有它
class PaymentService {
private final PaymentProcessor processor; // 構造器注入
public PaymentService(PaymentProcessor processor) { this.processor = processor; }
}
// 反模式:循環中 +=
String result = "";
for (String s : list) result += s; // 每次循環隱式 new StringBuilder + toString()
// 最佳:顯式 StringBuilder
StringBuilder sb = new StringBuilder(list.size() * 16); // 預估容量
for (String s : list) sb.append(s);
String result = sb.toString();
// Java 8+ Stream
String result = list.stream().collect(Collectors.joining());
IOException, SQLException)NullPointerException, IllegalArgumentException)| 策略 | 適用場景 | 示例 |
|---|---|---|
| 不可變對象 | 共享只讀數據 | String, LocalDate, Record, final 字段 |
| 線程封閉 | 非線程安全對象 | 局部變量、ThreadLocal、單線程事件循環 |
| 安全發布 | 跨線程傳遞 | volatile, final, 線程安全集合、Executor |
| 同步機制 | 共享可變狀態 | synchronized, Lock, Atomic*, Concurrent* |
《Effective Java》原則非教條,而是經過驗證的工程經驗結晶。核心哲學:
java.util.concurrent, Stream, Record, Sealed Class將這 13 條原則內化為編碼習慣,配合現代工具鏈,可構建高質量、高性能、可維護的 Java 系統。