thinking in java (五) ----- equals()方法
阿新 • • 發佈:2018-11-10
equals()
equals()方法用來比較兩個物件是否相等,父類是Object。其中在String中的equals()原始碼如下
y
物件都是由引用reference和物件例項組成的。“==”是用來比較兩個引用型別的reference,所以Object中的equals()方法是比較兩個引用型別的reference是否相等。和"=="的效果是一樣的。但是我們可以看到原始碼中,如果物件是String型別的話,就會進行內容上的比較。實際上,在JDK中,Msth,String等封裝類都對equals()方法進行了重寫。
在java規範中,應該使用的幾個規則:
equals方法在飛空物件引用上實現相等關係
- 自反性:對於任何非空引用X,X.equals(X)都應該返回true
- 對稱性:對於任何非空引用X和Y,當且僅當X.equals(Y)才為true時,Y.equals(X)才為true
- 傳遞性:對於任何非空引用X,Y,Z.如果X.equals(Y)為true。Y.equals(Z)為true,那麼X.equals(Z)為true
- 一致性:對於任何非空引用X,Y,多次呼叫X.equals(Y)始終為true或者始終為false,前提是XY中資訊並沒有被修改
- 對於任何非空引用X,X.equals(NULL)都應該返回false
重寫equals注意事項(不用instanceof關鍵字判斷型別)
眾所周知,instanceof關鍵字的作用是判斷左邊物件是否是右邊的例項,返回boolean型別的資料,可以用來判斷繼承中的子類例項是否是父類的實現。也就是說子類的例項instanceof父類,也會返回true。示例如下
父類Person
public class Person { protected String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(String name){ this.name = name; } public boolean equals(Object object){ if(object instanceof Person){ Person p = (Person) object; if(p.getName() == null || name == null){ return false; } else{ return name.equalsIgnoreCase(p.getName()); } } return false; } }
子類Employee
public class Employee extends Person{
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Employee(String name,int id){
super(name);
this.id = id;
}
/**
* 重寫equals()方法
*/
public boolean equals(Object object){
if(object instanceof Employee){
Employee e = (Employee) object;
return super.equals(object) && e.getId() == id;
}
return false;
}
}
測試類
public class Test {
public static void main(String[] args) {
Employee e1 = new Employee("chenssy", 23);
Employee e2 = new Employee("chenssy", 24);
Person p1 = new Person("chenssy");
System.out.println(p1.equals(e1));
System.out.println(p1.equals(e2));
System.out.println(e1.equals(e2));
}
}
返回結果
true
true
false
在測試類裡面定義了兩個員工和一個普通人,都是同名,但是肯定不是同一個人,但是返回比較結果卻不是false false false,
這就是因為Person中的equals方法中是用 的instanceof判斷型別,Employee繼承與Person,型別判斷結果為true,而name也相同,所以結果為true。
因此重寫equals的時候,需要進行型別判斷就使用getClass,
其中Person中的equals方法修改為:
public boolean equals(Object object){
if(object != null && object.getClass()== this.getClass()){
Person p = (Person) object;
if(p.getName() == null || name == null){
return false;
}
else{
return name.equalsIgnoreCase(p.getName());
}
}
return false;
}