場景:本周在完成一個公司業務功能時,在判斷是否為代叫單時調用了equal方法:
PublishOrderType.HELP_ORDER.equals(valetOrderExtraInfoDO.getHelpFlag())
HELP_ORDER為枚舉變量,比較的getHelpFlag()返回值為Integer,使得所有情況都返回false,導致業務邏輯錯誤
分析原因:equal為java的Object中的方法,因此除了基本類型外其他所有類型都可以調用,Object中方法定義如下:
public boolean equals(Object obj) { return (this == obj); }
當不同類型進行比較時,如果不是可以隱式轉換,一般返回false。比較時應當比較枚舉型的code,代碼如下:
PublishOrderType.HELP_ORDER.getCode().equals(valetOrderExtraInfoDO.getHelpFlag())
equal方法:
大家都知道,對於內置類型,使用==兩邊的值大小,而對於超類Object派生的類型,與==相比,equal方法比較的是內容,而==比較的內存地址,java中JDK提供的常用類都equal方法進行了重寫,比如:
枚舉類Enum:
public final boolean equals(Object other) { return this==other; }
整型類Integer:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false;
}
雙精度浮點類Double:
public boolean equals(Object obj) { return (obj instanceof Double) && (doubleToLongBits(((Double)obj).value) == doubleToLongBits(value)); }
字符串類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;
}
注意:上面判斷是不是同一個類是使用的是instanceof,這個詞的含義是判斷其左邊對象是否為其右邊類的實例或者子類的實例,而上面的幾個類在定義時使用了final,也就是說不允許繼承,因此可以使用該關鍵字,在自己編寫equal方法時,需要使用.getClass() == this.getClass()判斷類型是否一致;
equal方法有以下五個性質:
- 自反性
- 對稱性:不管誰調equal方法都不會影響結果
- 傳遞性
- 一致性:多次比較不會影響判斷結果
- 任何非空對象與調用equal(null)均返回false
java中需要選用合適的方法比較
- 對象域,使用equals方法 。
- 類型安全的枚舉,使用equals或== 。
- 可能為null的對象域 : 使用 == 和 equals 。
- 數組域 : 使用 Arrays.equals 。
- 除float和double外的原始數據類型 : 使用 == 。
- float類型: 使用Float.floatToIntBits轉換成int類型,然后使用==。
- double類型: 使用Double.doubleToLongBit轉換成long類型,然后使用==。
總的來說:類一般調用equal判斷,當然首先需要對類進行判空,除了float和double之外的內置類型直接使用==進行內容比較,而float和double使用Float和Double的方法比較,也可以先生成Float或者Double對象調用equal方法,從前面Double的equal方法中可以看出,實質上還是調用了[float/double]To[Int/Long]Bit方法,建議直接使用該方法,避免不必要的開銷。
參考:http://www.cnblogs.com/chenssy/p/3416195.html
