JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java 新手區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 [新手必看] Java字串的比較 [精華]
piggy

piggy



發文: 333
積分: 2
於 2003-09-21 00:09 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
很多老問題一直被新手提出來問
我把我之前在Java週報上發表過舊的文章貼上來
希望對初學者觀念的釐清有點幫助
眨在這,下次再問類似的問題
browser就別客氣,殺無赦吧~~~~

-------------------------------
原文刊登在 2002/09/12 Java 週報上

初學Java的人﹐在學習的過程中遇到的第一個不能理解的問題﹐通常就是
字串的比較問題﹐因為他們實在不能理解明明兩個"一樣"的字串﹐為什麼
有時在做相等的比較運算時會得到ture的結果﹐可是有時得到的結果確是
false?這個問題在網路上常常都被提出來討論﹐已經算是一個FAQ到不能
FAQ的問題﹐也許是那些初學者們都沒有買到一本好的教科書﹐書中並沒有
教導他們正確的認識字串﹐要是有認真地讀完筆者寫的書﹐應該就不會被
這個問題所困擾了。好吧!大家都是窮學生買不起五百塊以上的書﹐那筆
者就藉著Java週報的一角﹐詳細地說明字串的比較運算。

嚴格說起來﹐字串在Java中也是一個完整的物件﹐兩個物件要做比較時﹐
首先你得先想清楚你想要比較的東西是什麼。舉個例子來說吧﹐日常生活
中婆婆媽媽們聚在一起總是喜歡比較來比較去的﹐有時後比的是誰家的孩
子功課比較好啦﹐誰的老公賺的錢比較多啦等…。人也是物件的一種﹐當
你把兩個人做比較時﹐你一定是把這兩個人身上的某一個屬性拿出來比較
﹐比如說身高、體重、成績等等﹐所以你要說這兩個人完全相同時﹐一定
是你所拿出來比較的每個屬性的內容都相同。另外一種觀點的比較方式是
﹐一個人有時會有好幾個不同的綽號﹐別的人要經由比較確認之後﹐才知
道原來這幾個綽號指的都是你這個人。

話說回來﹐在Java程式中﹐你要比較兩個物件時﹐首先你要確認要比較的
是兩件物件的內容?還是比較兩個物件變數是否指向同一個物件?如果你
是要比較兩個物件的內容時﹐請使用該物件所提供的"equals"方法。例如:

String str1 = new String("hello");
String str2 = new String("hello");
boolean b1 = str1.equals(str2);
booealn b2 = str2.equals(str1);

上例中用誰的equals方法來使用﹐結果都是一樣的(都是true)﹐不過如果
str1和str2是兩個不同的類別物件﹐意義可就不太一樣了﹐這個問題有空
再說。如果你比較個物件變數指的是不是同一個物件﹐那你就得使用比較
算的"=="運算子。例如:

String str3 = new String("hello");
String str4 = new String("hello");
String str5 = str3;
boolean b3 = str3 == str4;
boolean b4 = str3 == str5;

b3的結果是false﹐b4的結果是true。不知道筆者這樣的解說﹐大家應該
可以清楚的知道什麼時候要使用equals方法﹐又什麼時後要使用"=="運算子。
話再說回來﹐會令初學者感到困惑的是類似下面的例子:

String str6 = "hello";
String str7 = "hello";
boolean b5 = str6.equals(str7);
boolean b6 = str6 == str7;

b5的結果是true﹐b6的結果也是true。為什麼b3的結果會是false﹐而b6
的結果卻是true呢?上面幾個例子中的字串物件﹐不都是"hello"這個字
串嗎?你只說對了一半﹐上面例子中str1到str7所指向的字串物件﹐它
們的"內容"都是"hello"這幾個字母沒錯﹐可是它們指向的可不都是同一
個字串物件!str1到str4這四個物件變數指向的字串物件﹐是經由標準
的物件產生方式(new)所產生出來的﹐就算內容一樣﹐可是還是不同的物
件。就像兩個雙胞胎來說﹐甚至兩個用複製出來的人﹐就算所有的屬性
都一樣﹐兩個人還是不同的個體﹐在地球上佔用不同的空間。==運算子
既然比較的是兩個物件變數是否指向的是同一個物件﹐所以b3的結果會
是false就是這個原因囉。

那b6的結果為什麼會是true呢?這是Java為了效能的考量﹐而使用的一
種技巧。因為字串對於一個應用程式來說﹐使用上是非常的頻繁的﹐如
果每個相同內容的字串物件﹐都佔用不同的記憶空間不是很浪費嗎?而
且JVM也要去處理這些可能只用過一次就不再使用的字串。因此﹐當你用
雙引號來產生一個字串物件時﹐JVM會先到記憶體中一個名叫String Pool
的地方去查詢一下﹐是否裡面已經有這個字串了﹐如果有則直接拿出來
使用;如果沒有就產生一個新的放到裡面去。所以str6和str7指向的字
串物件﹐都是在Stirng Pool中的hello字串物件﹐既然兩個物件變數指
向的是同一個物件﹐那麼用==運算子比較的結果當然就是true了。

被搞的昏頭轉向了嗎?其實就記住筆者最前面所說的﹐當你要比較的是
兩個物件的內容相不相等時﹐請用equals方法﹐如果要比較的是兩個物
件變數指向的是不是同一個物件時、請用==運算子。這樣一來﹐不管是
一般的物件還是字串物件在比較時﹐你就不會感到困惑了。


piggy edited on 2003-09-21 00:17
reply to postreply to post
An Apple a day, keeps M$ away
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
getch





發文: 15
積分: 0
於 2004-05-04 17:06 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
但這種情形
String str1=new String("hello");
String str2="hello";
boolean arg=(str1==str2);
又會得到false
是因為new所產生的物件不是在String pool的關係,所以str2在String pool找不到相同的字串,因此才創造一個新的物件嗎?


reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
hellfire

大爆炸!!??



發文: 24
積分: 0
於 2004-05-04 21:17 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
str1做了兩件事
創造"hello"字串放到pool中
再根據它的內容做出一個新的字串

str2則是從pool中取得"hello"

所以才會得到false


reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:hellfire]
hkdennis2k





發文: 1926
積分: 6
於 2004-11-08 12:33 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hellfire wrote:
str1做了兩件事
創造"hello"字串放到pool中
再根據它的內容做出一個新的字串

str2則是從pool中取得"hello"


不,
在compile 時, java 檔內的所有 hardcode 了的 string
會被找出來, 作為 const, 共用一個 char[]

比較像這個
1
2
3
4
static final String _STRING1=new String("hello".toCharArray());
.......
String str1=new String(_STRING1);
String str2=_STRING1;


reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:hkdennis2k]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2004-11-12 03:05 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
hkdennis2k wrote:
不,
在compile 時, java 檔內的所有 hardcode 了的 string
會被找出來, 作為 const, 共用一個 char[]

比較像這個
1
2
3
4
static final String _STRING1=new String("hello".toCharArray());
.......
String str1=new String(_STRING1);
String str2=_STRING1;



現在是在討論兩個 statement runtime 的行為,你講的是編譯期的事。

主要的差別在於使用 new operator 建構 String object 即使其內容在 VM runtime maintain 的 string pool 裡有相同的,依然會建構新的 String object,直接用 string literal 的寫法則是 VM 到 class const pool 去找對應的字串,如果 string pool 已經有相同內容的就使用 string pool 裡的,否則就依照 const pool 裡 string 內容建構 String object,並放到 string pool 裡。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
zbbert





發文: 5
積分: 0
於 2005-06-15 15:35 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
写得太好的。让我豁然开朗。谢谢

reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
lqding1980





發文: 3
積分: 0
於 2005-06-27 19:33 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
支持Duncan 的说法!

reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
edgar888





發文: 2
積分: 0
於 2005-07-21 19:58 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
從來沒有好好思考過這問題,謝謝分享

reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
JavaPiano





發文: 2
積分: 0
於 2005-07-25 02:01 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我看過書,然後再看一次原PO的說明之後,
真的豁然開朗了,觀念更清楚了。
謝謝!


reply to postreply to post
音樂 我用鋼琴來詮釋
程式 我用Java來撰寫
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
jzzxh

馬達~乎哈~



發文: 26
積分: 0
於 2005-08-04 21:36 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
piggy wrote:
很多老問題一直被新手提出來問
我把我之前在Java週報上發表過舊的文章貼上來
希望對初學者觀念的釐清有點幫助
眨在這,下次再問類似的問題
browser就別客氣,殺無赦吧~~~~

-------------------------------
原文刊登在 2002/09/12 Java 週報上

str1和str2是兩個不同的類別物件﹐意義可就不太一樣了﹐這個問題有空
再說。

不同的類別物件要怎用equals阿!


reply to postreply to post
~如果你想跟咖啡~一輩子為伴!就必要有必死決心~
-------- Keep Running now(); ---------
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
ljty2008





發文: 2
積分: 0
於 2006-10-23 21:10 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
從來沒有好好思考過這問題,謝謝分享

reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
wen8304





發文: 1
積分: 0
於 2006-10-26 21:18 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
没想到
真是豁然开朗阿!


reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
ayumi007





發文: 24
積分: 0
於 2006-12-29 17:48 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
謝謝啦.......我終於都白明了耶........
就是用new與沒有new的分別.........
是比較"內容"及比較"指向的物件"的分別耶.........
太好啦...........


reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
tolby0817





發文: 6
積分: 0
於 2008-09-12 01:48 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
終於明白了
謝謝大大的說明歐!!!


reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
johnxxx





發文: 1
積分: 0
於 2008-09-15 23:29 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
真的太謝謝了,這問題也一直困擾著我~!!

reply to postreply to post
作者 Re:[新手必看] Java字串的比較 [Re:piggy]
zhhaojie





發文: 9
積分: 0
於 2010-09-03 20:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
1
2
3
老師說,了解內存很重要的
 


reply to postreply to post
» JWorld@TW »  Java 新手區

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8