String類中的equals方法與Object類中equals方法的區別
阿新 • • 發佈:2018-10-31
今天在無意中發現一個小知識點,難度不大就是簡單和大家分享一下。
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));//true
System.out.println(str1.hashCode());//96354
System.out.println(str1.hashCode());//96354
結果為true沒有什麼異議,我們都知道equals比較的是兩個字串的記憶體地址。那麼str1與str2的hashCode為什麼相同呢?因為字串的hashCode是由內容匯出的,這裡也就說明了str1與str2有著相同的內容(因為hashCode相同啊)。接著我們來看String類的jdk原始碼
public boolean equals(Object anObject) {
//只要兩個字串的引用相同就返回true(這裡不再贅述常量池的知識)
if (this == anObject) {
return true;
}
/*為什麼會出現這一步比較呢?如果現在String str1 = new String("張三");這樣一個簡單的字串和一個自己定義的Student類中的name = "張三"比較的話,它的意義就出現了,先將其強轉為String型別,比較長度接著將字串賦值給字元陣列比較每一個值*/
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;
}
從原始碼中我們不難看出使用equals方法比較兩個字串的本質還是在使用==做比較。(原始碼註釋是我自己加的)
Object類中的equals方法
Employee emp1 = new Employee("張三", 5000, 2005, 5 ,5);
Employee emp3 = new Employee("張三", 5000, 2005, 5 ,5);
System.out.println(emp3.equals(emp1));
這段程式碼如果我說前提條件直接問你結果,我相信會有一部分人直接回答是true(這也是我寫這篇文章的目的)。
如果在Employee類中沒有重寫equals方法的話那麼其實結果是false。我們在初學equals方法的時候都認為equals方法比較的是內容,只要內容相同就是true(最起碼我一開始是這麼認為的)。如果在Employee類中沒有重寫equals方法它呼叫的就會是Object類中的equals方法,我們來看jdk中的原始碼:
public boolean equals(Object obj) {
return (this == obj);
}
我看錯了嗎?這就是原始碼就這麼一點,是的!現在你知道為什麼直接呼叫Object的equals方法為什麼是false的吧。這就是我們為什麼要經常強調,為每一個類重寫equals方法。為什麼需要重寫hashCode和toString方法我將在以後為大家整理。