作者:泥沙磚瓦漿木匠 網(wǎng)站:http://blog.csdn.net/jeffli1993 個(gè)人簽名:打算起手非凡寫(xiě)出鴻篇巨作的人,常常堅(jiān)持不了完成第1章節(jié)。 |
說(shuō)起String,大家最熟習(xí)不過(guò)了。我也是那末說(shuō)過(guò),但是恍如這熟習(xí)的里面也有很多細(xì)節(jié),或是我們沒(méi)掌握的東西。常常有很多舊東西里面爆出很多光點(diǎn)。比如,作者泥瓦匠近期在冬季的牛崽褲里面搜出了1張100現(xiàn)金(不宜樂(lè)乎)?;氐秸},我們下面以下幾點(diǎn)講下String。分兩個(gè)部份:
基礎(chǔ)部份:(JDK源碼 文檔)
擴(kuò)大部份:
樓主不是大牛級(jí)別的人物,泥瓦匠1直認(rèn)為的是“打算起手非凡寫(xiě)出鴻篇巨作的人,常常堅(jiān)持不了完成第1章節(jié)?!彼裕僦I盤(pán),聽(tīng)著喜歡的音樂(lè)。幽默的對(duì)你說(shuō)我的理解體會(huì)。
(希望大牛指出毛病,萬(wàn)分感謝!)
懷著初次見(jiàn)你的心情,泥瓦匠和你1起打開(kāi)JDK1.7文檔。我最近想寫(xiě)1些關(guān)于JDK1.7的理解,都知道JDK8出來(lái)了,新特性我準(zhǔn)備下階段有空學(xué)習(xí)。
泥瓦匠想說(shuō),瀏覽E文文檔有益于體會(huì)原汁原味。但畢竟國(guó)內(nèi)大牛翻譯的很不錯(cuò)了,我們不加評(píng)判,喜歡哪一種自己挑。能抓老鼠,能解決實(shí)際項(xiàng)目,適應(yīng)業(yè)務(wù)環(huán)境的就是你學(xué)到了。請(qǐng)看下面的小例子:
清單1.1
泥瓦匠,你不是在忽悠我嗎?這么簡(jiǎn)單的程序,你想說(shuō)甚么。說(shuō)實(shí)在確切是基礎(chǔ),但基礎(chǔ)扎實(shí)才能有更高的突破。就想泥瓦匠默默為自己,為家人為未來(lái)打基礎(chǔ)。
可以見(jiàn),String是不需要用new來(lái)創(chuàng)建1個(gè)新對(duì)象的類。它是不可變的(Constant),其值(像"abc"創(chuàng)建后,不可改變)。自然,String其實(shí)實(shí)現(xiàn)了基本類型char的序列的功能,因此中文名“字符串”。這里大家有可能疑惑,泥瓦匠就找到JDK源碼證據(jù)給你們看:
這段代碼是來(lái)自JDK1.7源碼里面的,char型value數(shù)組的情勢(shì)組成了String類的內(nèi)容。其操作就是針對(duì)value數(shù)組操作。這樣想是不是豁然開(kāi)朗,然后心里自喜“so easy”。其實(shí)難點(diǎn)下面,大家漸漸看下去。
照舊看代碼清單1.1,Java提供了1個(gè)特殊的連接操作符(concatenation operator)+ 用于直接來(lái)拼接字符串。其中操作經(jīng)常使用的方法羅列以下:
隨著泥瓦匠運(yùn)行下清單1.1,你可以看到打印出來(lái):
有人看到這個(gè)會(huì)大吃1驚,然后質(zhì)問(wèn)說(shuō)“老師說(shuō),String 和 == 沒(méi)關(guān)系,你是否是瞎扯淡”。哈哈,我只能說(shuō),只不過(guò)修行在實(shí)際。舉個(gè)小栗子吧。
看下面清單1.2
看到這里,你是不是覺(jué)得這么簡(jiǎn)單,心里想著肯定是“false,泥瓦匠真逗?!边\(yùn)行下,結(jié)果卻是
泥瓦匠的記憶宮殿:就是相當(dāng)于 泥瓦匠和我的親姐姐比較我們兩個(gè)的爸爸,畢竟的爸爸都是那1個(gè),固然是true。
"a" + "b"的生命是怎樣樣的呢?網(wǎng)絡(luò)牛人有些反編譯會(huì)發(fā)現(xiàn)實(shí)際上是類似下面的進(jìn)程:
究竟JVM是怎樣把"a" + "b"和"ab"知道他們是1樣的呢。我們回顧下,由于String是不可變類,也就是靜態(tài)Java語(yǔ)言的特點(diǎn)。這觸及到JVM的優(yōu)化方案。但JVM很死板,它不會(huì)很人工智能的像人腦,它會(huì)的只是它能處理的,所以好好了解JVM有助于開(kāi)發(fā)更好的額程序。比如定義1個(gè)ab字符串常量夠了,它不會(huì)在再 子串 a b。這就是它的優(yōu)化方案。
泥瓦匠的記憶宮殿:這就是偷懶思想,今天我要見(jiàn)我爸爸,明天姐姐要見(jiàn)爸爸。合并下唄,后天1起去見(jiàn)爸爸。
就此我們可以得出結(jié)論:編譯器給我?guī)?lái)它對(duì)程序的優(yōu)化,為了提升程序的效力和內(nèi)存資源等,所以我們可以明白,如何掌握其特性寫(xiě)出更好的代碼。
補(bǔ)充個(gè)例子,看看你們真的掌握沒(méi)?
如果猜到了,證明你真懂了。泥瓦匠還是耐心的講授下:
第1個(gè)false:b是包括了1個(gè)常量和1個(gè)援用的值,所以。
第2個(gè)false: 你也能夠猜到外部方法的常量在本方法只是1個(gè)援用。所以。
結(jié)論以下:我們現(xiàn)在如果不知道JVM怎樣在編譯時(shí)期優(yōu)化,我們就漸漸了解它們。
這個(gè)例子不好寫(xiě),泥瓦匠就帶你們看看源碼等。equals其實(shí)不陌生,相信大家的系統(tǒng)里面有很多設(shè)計(jì)到這個(gè)方法。
其實(shí)equals是實(shí)現(xiàn)了Object的equals方法,而在Object的equals:
它其實(shí)就是實(shí)現(xiàn)了 == 比較內(nèi)存的內(nèi)容。
Q:泥瓦匠,為何String要重寫(xiě)Object,這不致使意義不1致了嗎?
A:非也非也,String是String,String用來(lái)處理的事物邏輯和業(yè)務(wù)和Object完全不同。equals顧名思義等于,等于不表示完全相等。而是1樣或相似。正所謂業(yè)務(wù)看情況,比如泥瓦匠處理得金融數(shù)據(jù)1般小數(shù)點(diǎn)10幾位,那請(qǐng)問(wèn)你還會(huì)在意小數(shù)點(diǎn)10位后的的值嗎,當(dāng)它們比較的時(shí)候,你不會(huì)在意,所以這就是相似。
那末我們就看1下String實(shí)現(xiàn)的equals方法:
簡(jiǎn)單描寫(xiě)下,就是遍歷兩個(gè)數(shù)組最好的條件下,就是要末長(zhǎng)度不同,要末前面幾個(gè)不同。直接返回false。
Q:如果碰到大字符串這就悲劇了。所以1些大字符串怎樣處理呢。
A:其實(shí)實(shí)際中,大字符串也難見(jiàn)。但說(shuō)處理的話,大字符串匹配可以斟酌分割匹配或是啥的這里就不展開(kāi)了。
Q:equals重寫(xiě) 和 hashCode 有關(guān)系嗎?
A:這里我們要先說(shuō)明hashCode方法提供對(duì)象的hashCode值,返回與默許的System.identityHashCode()1致。其廣泛用于集合框架。到后面我也會(huì)講到。hashCode的源于計(jì)算機(jī)的比較源于數(shù)字,而不是對(duì)象。所以1個(gè)hashCode值標(biāo)識(shí)1個(gè)對(duì)象,產(chǎn)生了對(duì)象相干的很多算法。但是默許的hashCode犯法會(huì)發(fā)起對(duì)本地的調(diào)用開(kāi)消很大。
intern大家就有點(diǎn)陌生了。我們首先得普及下常量池的概念,常量池(constant pool)指的是在編譯期被肯定,并被保存在已編譯的.class文件中的1些數(shù)據(jù)。它包括了關(guān)于類、方法、接口等中的常量,也包括字符串常量。然后看看下面的例子:
當(dāng)調(diào)用 intern()方法時(shí),JVM 會(huì)在這個(gè)常量池中通過(guò) equals()方法查找是不是存在等值的 String,如果存在,則直接返回常量池中這個(gè) String 對(duì)象的地址;沒(méi)有找到,則會(huì)創(chuàng)建等值的字符串,返回其地址。
思考提升:這有甚么用呢?
答曰:可以用于1些常量的存儲(chǔ)比較,枚舉(枚舉底層就是字符串,哈哈)。當(dāng)想常量比常量,多數(shù)的情況下,斟酌效力則選擇 intern()而不是equals。
String是Java基礎(chǔ)組件重要的1部份。我漸漸的總結(jié)的J2EE Java的組件體系,然后增加內(nèi)容進(jìn)去。還是那句話,泥瓦匠想說(shuō):
如以上文章或鏈接對(duì)你有幫助的話,別忘了在文章按鈕或到頁(yè)面右下角點(diǎn)擊 “贊1個(gè)” 按鈕哦。你也能夠點(diǎn)擊頁(yè)面右側(cè)“分享”懸浮按鈕哦,讓更多的人瀏覽這篇文章