首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Effective Java 方法設計精華:參數驗證、防禦性複製、方法簽名、慎用重載

     編輯:Java 程式設計入門

第 38 條:檢查參數有效性

Public 方法

  • 在 Javadoc @throws 標記說明違反限制時拋出的異常。
  • 範例:BigInteger.mod() 檢查模數必須為正,否則拋出 ArithmeticException。

非 Public 方法

  • 使用斷言 (assert) 檢查參數。
  • 斷言預設關閉,需啟動:JVM 參數 -ea 或 -enableassertions;IntelliJ IDEA 在 VM Options 加入 -ea。

第 39 條:必要時進行防禦性複製

核心觀念:假設客戶端會盡全力破壞類別的約束條件,進行防禦性程式設計。

案例:Period 類別

看似不可變,但 Date 可變,客戶端可透過取得的參考修改內部狀態:


// 攻擊 1:建構子參數
Date start = ...; Date end = ...;
Period p = new Period(start, end);
start.setYear(2017); // 修改了 Period 內部狀態

// 攻擊 2:存取器回傳可變內部參考
p.getEnd().setYear(1998); // 修改了 Period 實例

解決方案:防禦性複製

  • 建構子:對每個可變參數建立副本 new Date(start.getTime()),複製後再驗證約束。
  • 存取器:回傳可變內部欄位的副本 return new Date(start.getTime())。

適用場景

  • 不可變類別
  • 客戶提供的物件進入內部資料結構(建構子/方法參數)

Map 鍵值陷阱:使用可變物件 (如 Date) 作為 Map Key,修改後導致無法查找。解決:用不可變值 (如 date.getTime() 的 long 值) 作為 Key。

第 40 條:謹慎設計方法簽名

  • 慎選方法名稱(參考 Google Java Style)
  • 別過度提供便利方法
  • 避免過長參數列表(目標 ≤ 4 個)
  • 同類型長參數列表極易弄錯順序

縮短參數列表三招

  1. 拆分為多個方法
  2. 建立輔助類別 (Parameter Object)
  3. 使用 Builder 模式
  • 參數類型優先用介面 (Map 而非 HashMap)
  • boolean 參數優先用兩元素枚舉 (TemperatureScale {F, C})

慎用重載

重載解析是靜態的(編譯期決定),覆寫是動態的(執行期決定)。

經典陷阱


class CollectionClassifier {
    static String classify(Set s) { return "Set"; }
    static String classify(List l) { return "List"; }
    static String classify(Collection c) { return "Unknown"; }
}
Collection[] cs = { new HashSet<>(), new ArrayList<>(), new HashMap<>().values() };
for (Collection c : cs) System.out.println(classify(c));
// 輸出三次 "Unknown"!因為編譯期類型皆為 Collection

重載方法選擇在編譯期根據宣告類型決定。避免同類型參數的重載,或確保不會產生歧義。

覆寫是動態的


Wine[] wines = { new Wine(), new SparklingWine(), new Champagne() };
for (Wine w : wines) System.out.println(w.name());
// 輸出:wine, sparkling wine, champagne
// 覆寫方法在執行期根據實際物件類型動態分派

總結

嚴謹的參數驗證、必要時的防禦性複製、清晰的方法簽名、謹慎使用重載,是編寫健壯、可維護 API 的關鍵。區分靜態重載與動態覆寫的語意差異,避免陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved