在《java核心技術卷1》中建議equals方法的寫法:
1.如果子類擁有自己的相等概念,則使用getclass比較。
public boolean equals (Object otherObject){
if(this == otherObject) //判斷是否引用同一個對象
return true;
if(otherObject == null) //判斷是否爲null
return false;
//如果equals的語義在每一個子類中都有改變,則使用getclass判斷類名必須一致。如果子類和超類都使用getclass,則子類定義equals時先判斷超類的equals,即if(! (super.equals(otherObject))) return false;
// if(getclass() != otherObject.getClass)
// return false;
ClassName other = (ClassName) otherObject; //轉型爲同類對象
//比較需要判定的實例域。爲了防備field2爲null,使用Objects.equals方法,當兩個實例域都爲null時判定爲true,如果使用field2.equals(other.field2)則都爲null時會放回false。
return field1 == other.field1 && Objects.equals(field2,other.field2);
}
比如通過比較名稱、薪水、入職日期判斷是否爲同一個僱員。如果經理類是僱員類的子類,要判斷是否爲同一個經理,則先用僱員的equals判斷,如果通過再判斷經理類中獨有的實例域是否相等。
2.如果由超類決定相等的概念,則使用instanceof比較。
public final boolean equals (Object otherObject){
if(this == otherObject) //判斷是否引用同一個對象
return true;
if(otherObject == null) //判斷是否爲null
return false;
//如果equals在每個子類中都有相同的語義,即子類判斷equals的原則都一樣,則用instanceof。並且可以將equals方法定義爲final表示不用更改,也就是將這個方法靜態綁定。
if(!(otherObject instanceof ClassName))
return false;
ClassName other = (ClassName) otherObject; //轉型爲同類對象
//比較需要判定的實例域。爲了防備field2爲null,使用Objects.equals方法,當兩個實例域都爲null時判定爲true,如果使用field2.equals(other.field2)則都爲null時會放回false。
return field1 == other.field1 && Objects.equals(field2,other.field2);
}
比如通過僱員的ID來判斷是否爲同一個僱員,這樣經理同樣也只需要判斷ID,不需要覆蓋僱員的equals方法。