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

Java 經典編程總結(上):equals/hashCode/compareTo/clone 最佳實踐與防禦性編程

     編輯:Java 相關知識

一、核心方法正確實現

1. equals() 契約

public boolean equals(Object obj) {
    if (!(obj instanceof Person)) return false;
    Person other = (Person) obj;
    return name.equals(other.name) 
        && birthYear == other.basicYear 
        && Arrays.equals(raw, other.raw);
}
  • 參數**必須為 Object**,不可為具體類
  • equals(null) 返回 false,不拋異常
  • 基本類型用 ==,數組用 Arrays.equals()
  • 覆寫 equals 必須覆寫 hashCode(),保持一致性

2. hashCode() 實現

public int hashCode() {
    return a.hashCode() + b.hashCode() + c + Arrays.hashCode(d);
}
  • x.equals(y) == true → x.hashCode() == y.hashCode()(強制)
  • hashCode() != y.hashCode() → equals() == false(逆否命題)
  • 允許 equals() == false 但 hashCode() 相同,但應盡量分散以提升性能
  • 最簡實現 return 0 合法但會癱瘓 HashMap

3. compareTo() 實現

public int compareTo(Person other) {
    int cmp = firstName.compareTo(other.firstName);
    if (cmp != 0) return cmp;
    cmp = lastName.compareTo(other.lastName);
    if (cmp != 0) return cmp;
    return Integer.compare(birthdate, other.birthdate);
}
  • 實現 Comparable<T> 泛型版本,避免原始類型擦除警告
  • 只關心返回值**正負零**,具體數值大小無意義
  • Comparator.compare() 邏輯一致

4. clone() 深拷貝

public Values clone() {
    try {
        Values result = (Values) super.clone(); // 淺拷貝
        result.bars = result.bars.clone();      // 數組深拷貝
        result.hired = result.hired.clone();    // 可變對象深拷貝
        return result;
    } catch (CloneNotSupportedException e) {
        throw new AssertionError(e); // 不可能發生
    }
}
  • 調用 super.clone() 獲取淺拷貝對象
  • 基本類型、String、不可變對象無需處理
  • 所有可變引用類型(數組、對象)必須手動深拷貝
  • 實現 Cloneable 的類 clone() **不拋受檢異常**,捕獲後包裝或忽略

二、防禦性編程:不信任任何輸入

1. 數值檢查

int factorial(int n) {
    if (n < 0) throw new IllegalArgumentException("未定義");
    if (n >= 13) throw new ArithmeticException("溢出");
    if (n == 0) return 1;
    return n * factorial(n - 1);
}

2. 對象非空檢查

int findIndex(List<String> list, String target) {
    if (list == null || target == null) throw new NullPointerException();
    // ...
}

3. 數組索引/區間檢查

void frob(byte[] b, int index) {
    if (b == null) throw new NullPointerException();
    if (index < 0 || index >= b.length) throw new IndexOutOfBoundsException();
}
void frob(byte[] b, int off, int len) {
    if (off < 0 || off > b.length || len < 0 || b.length - off < len)
        throw new IndexOutOfBoundsException();
}

原則:顯式檢查所有前置條件,寧可拋異常也不可產生難以定位的邏輯錯誤。

三、數組高效操作:拒絕手寫循環

操作手寫循環標準庫優選
填充for(i) a[i]=vArrays.fill(a, v)
複製for(i) b[to+i]=a[from+i]System.arraycopy(a,from,b,to,len)
擴容/縮容新建數組循環複製Arrays.copyOf(a, newLen)
4字節↔int位運算組合手寫位運算(無庫方法),注意用 >>> 無符號右移

總結

這些「經典用法」看似基礎,實則是高質量 Java 代碼的基石。equals/hashCode 契約決定集合行為,clone 深拷貝關係數據隔離,防禦性編程構建健壯邊界,標準庫方法保證性能與正確性。**養成肌肉記憶,寫出經得起生產環境考驗的代碼。**

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