1. 程式人生 > >讀書筆記-《Effective Java》第8條:覆蓋equals時請遵守通用約定

讀書筆記-《Effective Java》第8條:覆蓋equals時請遵守通用約定

如果覆蓋equals方法的目的是判斷物件之間是否相等,那麼使用超類(Object)的方法即可。

 public boolean equals(Object obj) {
        return (this == obj);
    }

在覆蓋equals方法的時候,必須要遵守它的通用約定:

  • 自反性(reflexive)。對於任何非null的引用值x,x.equals(x)必須返回true。
  • 對稱性(symmetric)。對於任何非null的引用值x和y,y.equals(x)返回true,那麼xequals(y)也必須返回true
  • 傳遞性(transitive)。
    對於任何非null的引用值x、y、z,x.equals(y)返回true,並且y.equals(z)返回true,那麼x.equals(z)也必須​​​​​​​返回true。
  • 一致性(consistent)。對於任何非null的引用值x和y,只要equals的比較操作所用到的資訊沒有被修改,那麼多次呼叫equals方法結果必須與第一次呼叫保持一致。
  • 非空性。這個在equals中是要首先判斷的。

重寫equals方法的訣竅:

  • 使用==操作符檢查“引數是否為這個物件的引用”。 效能的優化。
  • 使用instanceof操作符檢查“引數是否為正確的型別”。
  • 把引數轉換成正確的型別
  • 對於該類中的每個“關鍵”域,檢查引數中的域是否與該物件中的域相匹配。
  • 編寫完成equals方法後,要檢查、測試是否符合約定。
  • 覆蓋equals時總要覆蓋hashCode。
  • 不要企圖equals方法過於智慧。
  • 不要將equals宣告中的Object物件替換為其他的型別。 @Override

jdk 1.8中String類的equals方法

   /**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }