----------------------------------------------------------------------------------------------------------------------
以下是 QQ 群上的聊天記錄,以及我的一些注釋。
狂風(fēng)掃落葉 10:23:08
為什么 String 類要重寫 Object 類的 equals 方法啊?
水圣 10:21:14
看看你代碼
狂風(fēng)掃落葉 10:23:08
不是 , 有朋友問我這個(gè)問題 , 我不知道怎么回答 ,
好像是為了區(qū)分 對(duì)像比較的時(shí)候 == 和 equals 的有所區(qū)別 ?
天天好心情 10:23:34
== 不是比較對(duì)象的
阿黃 10:24:15
我記得的好象是
== 實(shí)際上是比較的兩個(gè)字符串的物理內(nèi)存地址。
“ A ” == “ A ”結(jié)果肯定是不相等的
阿黃 10:24:47
其中“ A ”表示一個(gè)字符串
水圣 10:25:51
== 實(shí)際上是比較的兩個(gè)字符串的物理內(nèi)存地址
狂風(fēng)掃落葉 10:25:58
to 阿黃 你說的是字符串對(duì)象,他重寫了 Object 的 equals 方法
所以會(huì)那樣
midthinker 10:26:04
==比較對(duì)象的地址, equals 比價(jià)兩個(gè)對(duì)象的值(如果默認(rèn)繼承自 OBJECT ,則 equals 比較兩個(gè)對(duì)象地址), String class override 了 Object class 的 equals 方法,實(shí)現(xiàn)了自己的方法,所以 equals 比較的是實(shí)際值而非地址
阿黃 10:26:45
我說的就是這個(gè)意思了
midthinker 10:26:54
另外 String class 在 JAVA 中比較特殊的地方是他采取了值對(duì)象模式以及享元模式
midthinker 10:27:25
這意味著普通的比較會(huì)出現(xiàn)正確的結(jié)果
String a = "aaa";
String b = "aaa";
a == b is equals
midthinker 10:28:33
只覺上這個(gè)是錯(cuò)誤的,因?yàn)?/span> String 是對(duì)象,不是簡單數(shù)值,所以他們應(yīng)該是不同的對(duì)象,但這里他們是相同的,原因在于享元模式讓 aaa 保留下來,并再下次使用時(shí)賦予
midthinker 10:29:14
但是這樣就不對(duì)
String a = new String("aaa");
String b = new String("aaa");
a == b is false ????????????????????//????????? 其實(shí)講到這里應(yīng)該都清楚了 object 類的 equals() 跟 == 的作用是一樣的,但是繼承 object 類的 子類一般都會(huì)重寫 equals() 方法,這樣做的目的是為了 很好地區(qū)分 equals() 的作用, == 只負(fù)責(zé)比較兩個(gè)對(duì)象 的物理地址是否相同, equals() 方法負(fù)責(zé)比較兩個(gè)對(duì)象 的內(nèi)容(或者說是值, value )是否相等。//
阿黃 10:29:33
這種問題應(yīng)該屬于比較底層的了
沒事了可以看下
深入理解計(jì)算機(jī)系統(tǒng)。。。講解很精辟
狂風(fēng)掃落葉 10:30:34
受教
水圣 10:33:17
: "==" 和 equals 方法究竟有什么區(qū)別?
== 操作符專門用來比較變量的值是否相等。比較好理解的一點(diǎn)是:
int a=10;
int b=10;
則 a==b 將是 true 。
但不好理解的地方是:
String a=new String("foo");
String b=new String("foo");
則 a==b 將返回 false 。
對(duì)象變量其實(shí)是一個(gè)引用,它們的值是指向?qū)ο笏诘膬?nèi)存地址,而不是對(duì)象本身。 a 和 b 都使用了 new 操作符,意味著將在內(nèi)存中產(chǎn)生兩個(gè)內(nèi)容為 "foo" 的字符串,既然是“兩個(gè)”,它們自然位于不同的內(nèi)存地址。 a 和 b 的值其實(shí)是兩個(gè)不同的內(nèi)存地址的值,所以使用 "==" 操作符,結(jié)果會(huì)是 false 。誠然, a 和 b 所指的對(duì)象,它們的內(nèi)容都是 "foo" ,應(yīng)該是“相等”,但是 == 操作符并不涉及到對(duì)象內(nèi)容的比較。
對(duì)象內(nèi)容的比較,正是 equals 方法做的事。
看一下 Object 對(duì)象的 equals 方法是如何實(shí)現(xiàn)的:
boolean equals(Object o){
return this==o;
}
Object 對(duì)象默認(rèn)使用了 == 操作符。所以如果你自創(chuàng)的類沒有覆蓋 equals 方法,那你的類使用 equals 和使用 == 會(huì)得到同樣的結(jié)果。同樣也可以看出, Object 的 equals 方法沒有達(dá)到 equals 方法應(yīng)該達(dá)到的目標(biāo):比較兩個(gè)對(duì)象內(nèi)容是否相等。因?yàn)榇鸢笐?yīng)該由類的創(chuàng)建者決定,所以 Object 把這個(gè)任務(wù)留給了類的創(chuàng)建者。
看一下一個(gè)極端的類:
Class Monster{
private String content;
...
boolean equals(Object another){ return true;}
}
我覆蓋了 equals 方法。這個(gè)實(shí)現(xiàn)會(huì)導(dǎo)致無論 Monster 實(shí)例內(nèi)容如何,它們之間的比較永遠(yuǎn)返回 true 。
所以當(dāng)你是用 equals 方法判斷對(duì)象的內(nèi)容是否相等,請不要想當(dāng)然。因?yàn)榭赡苣阏J(rèn)為相等,而這個(gè)類的作者不這樣認(rèn)為,而類的 equals 方法的實(shí)現(xiàn)是由他掌握的。如果你需要使用 equals 方法,或者使用任何基于散列碼的集合( HashSet,HashMap,HashTable ),請察看一下 java doc 以確認(rèn)這個(gè)類的 equals 邏輯是如何實(shí)現(xiàn)的。
?
小豬 10:45:28
Class Monster{
private String content;
...
boolean equals(Object another){ return true;}
}
這個(gè)例子有點(diǎn)看不懂了。一個(gè) Monster 的類對(duì)象怎么會(huì)去跟一個(gè) Object 的類對(duì)象比較?
小豬 10:45:52
本身這樣的比較就沒意義吧?
不二 10:46:22
為什么沒意義
阿黃 10:46:41
恩
類好象都是從 object 繼承來的,應(yīng)該可以比較
水圣 10:46:57
比較極端而已
阿黃 10:47:17
一般的類都是默認(rèn)從 java? object 繼承
小豬 10:48:21
我小學(xué)用“像”造句 " 我像我爸爸 " 就被老師罵過啊。
midthinker 10:48:41
因?yàn)?/span> equals 方法再 Object class 中的定義為 public boolean equals(Object o);
當(dāng)子類方法 override 父類方法時(shí),函數(shù)申明特征必須相同,所以必須使用 Object ??// 這句話什么意思我還不是很懂。就 Monster 類來說 Object 是其父類,所以 Monster 的 equals() 的操作數(shù)必須是其父類的對(duì)象? //
阿黃 10:49:57
呵呵 ~~~
應(yīng)該沒人這樣造句吧
“我長的象我爺爺”
嘎嘎 ~~~~~~~~~~~~~~~~~~~
midthinker 10:50:19
一般 override equals method 的普通手法是
public boolean equals(Object o) {
? MyObject o = (MyObject) o;
? // TODO: compare them
? return xxx;
}
水圣 10:50:40
不是比喻句,但是是對(duì)的
水圣 10:50:44
哈哈
不敗の小儜 10:51:29
前面定義 OBJECT 應(yīng)該就是說什么類都能傳進(jìn)去跟他比較吧。。
小豬 10:52:47
MyObject o = (MyObject) o;// 是這句吧 ?
小豬 10:53:51
那這個(gè)轉(zhuǎn)型 要怎么寫 ?
midthinker 10:54:23
是
midthinker 10:54:33
就是上面那句
小豬 10:54:44
這個(gè)轉(zhuǎn)型怎么實(shí)現(xiàn) ?
不敗の小儜 10:54:54
。。
midthinker 10:55:11
呵呵語言特性,你把他理解為一個(gè)神奇的黑盒,完成你想要的功能就 OK 了
小豬 10:55:54
這個(gè)世界好神奇哦
『堂』天曉得 10:56:10
.............................
ぷ秋起雁歸ぷ 10:56:11
為什么這么說
小豬 10:59:37
?Class Monster{
private String content;
...
boolean equals(Monster another){ return true;}
} 這樣不可以么 ?
midthinker 10:55:11
危險(xiǎn) ...
Monster m1 = new Monster();
Monster m2 = new Monster();
m1.equals(m2) 永遠(yuǎn)相等,這真的是你想要的結(jié)果嗎?
?
小豬 11:01:49
我在 equals() 里面還要訪問 Monster 的 content 變量的 .
小豬 11:02:10
比較 content 內(nèi)容 , 然后再返回 true or false
midthinker 11:02:39
OK ,這是你的業(yè)務(wù)邏輯,我不知道這對(duì)不對(duì),你對(duì)此負(fù)責(zé) ?
小豬 11:02:41
做到真正的內(nèi)容比較是 equals 的職責(zé)嘛
midthinker 11:02:51
是的
midthinker 11:02:59
是內(nèi)容比較,或者成為 value 比較
不敗の小儜 11:03:40
自己新建的類, equals 比較的是引用還是內(nèi)容啊。。。
水圣 11:03:46
clone
midthinker 11:04:04
如果不 override equals method ,默認(rèn)為比較引用地址
不敗の小儜 11:04:29
Monster m1 = new Monster();
Monster m2 = new Monster();
m1.equals(m2)
不敗の小儜 11:04:34
那不是不相等么
不敗の小儜 11:04:41
2 個(gè)都 new 過了。。。
midthinker 11:05:01
他覆蓋了 equals 方法
不敗の小儜 11:05:07
哦
不敗の小儜 11:05:10
這個(gè)是內(nèi)部的?
小豬 11:05:15
語法上來說只進(jìn)行類型比較吧 ?
midthinker 11:05:38
equals 方法是一個(gè) public 訪問修飾符,所以他不應(yīng)該稱為內(nèi)部的
midthinker 11:05:56
他的接口在任何時(shí)候都被共享,只要你想調(diào)用
不敗の小儜 11:06:09
哦
小豬 11:12:37
兩個(gè)東西比較都是比較我們平時(shí)看得見的東西進(jìn)行比較的吧 ? 也就是外部可以訪問到的東西之間的比較吧 ? 如果兩個(gè)不同的類之間包含相同的 public 成員變量 . 你是怎么實(shí)現(xiàn)的 ?
midthinker 11:14:14
不懂你的意思?
midthinker 11:20:08
呵呵,假設(shè)。。。 one developer and one tester ,他們密切合作,進(jìn)行著緊張而忙碌的開發(fā)活動(dòng),突然你們的老板來到你們面前,并告訴你們之前程序的某個(gè)部分因?yàn)槟承┨厥庠虬l(fā)生了問題,你們的老板為此大發(fā)雷霆,甚至威脅扣除你們的獎(jiǎng)金,除非你們能夠說明誰犯了這個(gè)錯(cuò)誤,經(jīng)過分析你們發(fā)現(xiàn)這是一個(gè)各占 50 %的責(zé)任,大家認(rèn)為作為一個(gè) developer or Tester ,誰更有可能優(yōu)先向?qū)Ψ降狼福⒊姓J(rèn)錯(cuò)誤? ?
小豬 11:21:24
比如
class a {
?int a=1;
? private void a(){};
}
class b {
?int b=1;
?private void b(){};
}
這樣 b 里面包含了跟 a 一樣的一個(gè) int 變量 . 而我們調(diào)用這兩個(gè)類的時(shí)候只用到這兩個(gè)類對(duì)象的 int 變量的內(nèi)容也就是從類的用戶的角度來說這兩個(gè)類是可以相等的 . 那么是否需要寫一個(gè) a 和 b 之間進(jìn)行相等比較的 equals method 呢 ?
// 我提的問題有點(diǎn)鉆牛角尖了,事實(shí)上兩個(gè)不同類的對(duì)象之間沒有比較的意義,肯定是不同的。 //
----------------------------------------------------------------------------------------------------------------------