Java String詳解

使用Java語言進行編程食听,我們每天都要用到String類奸披,但是以前只是拿來就用邻寿,并不知道String類的實現(xiàn)原理和在內(nèi)存中是如何存在的蝎土,所以,是時候來仔細看看我們熟悉的String背后的故事了绣否。

1.Java內(nèi)存模型-常量池

Paste_Image.png
方法區(qū)(Method area)

(1)保存被加載類型的信息誊涯,包括類型信息(Type Information)和方法列表(Method Tables)。
(2)所有線程共享蒜撮,所以訪問方法區(qū)信息的方法必須是線程安全的搀罢。
(3)在JVM啟動的時候創(chuàng)建卖哎。
(4)存儲了每個類的結(jié)構(gòu)信息为迈,例如運行時常量池(Runtime Constant Pool)拾枣、字段和方法數(shù)據(jù)庆械、構(gòu)造函數(shù)和普通方法的字節(jié)碼內(nèi)容薇溃、還包括一些在類、實例缭乘、接口初始化時用到的特殊方法沐序。

運行時常量池(Runtime constant pool)

位于方法區(qū)中琉用,是每一個類或接口的常量池(Constant_Pool)的運行時表現(xiàn)形式,它包括了若干種常量:編譯器可知的數(shù)值字面量到必須運行期解析后才能獲得的方法或字段的引用策幼。

簡而言之邑时,當一個方法或者變量被引用時,JVM通過運行時常量區(qū)來查找方法或者變量在內(nèi)存里的實際地址特姐。

在類和接口被加載到JVM后晶丘,對應(yīng)的運行時常量池就被創(chuàng)建。

2.String連接案例解析

String常量
  • String常量的值是在常量池中的

JVM中的常量池在內(nèi)存當中是以表(hashtable)的形式存在的唐含, 對于String類型浅浮,有一張固定長度的CONSTANT_String_info表用來存儲文字字符串值,注意:該表只存儲文字字符串值捷枯,不存儲符號引用滚秩。
常量池中保存著很多String對象,并且可以被共享使用淮捆,因此它提高了效率郁油。

  • 在Java中,String對象是不可變的(Immutable)

在代碼中,可以創(chuàng)建多個某一個String對象的別名攀痊,但是這些別名的引用是相同的桐腌。

String的連接
  • JAVA虛擬機處理String的連接符+(concatenation)時會有不同處理

如果都是字符常量,那么只會生成一個蚕苇。
如果有變量哩掺,那么會調(diào)用StringBuilder,最后調(diào)用Sb的tostring涩笤。
連接符兩邊只要有一個不是字符串常量嚼吞,那就是說明那個變量是個地址的引用,引用指向的值編譯時無法知道的蹬碧。
String a = "123" (生成一個字符串常量)
String a = "123" + b (調(diào)用StringBuilder)

  • String a="a"+"b"+"c"在內(nèi)存中創(chuàng)建幾個對象舱禽?

甲骨文jdk(1.7),javac會進行常量折疊恩沽,全字面量字符串相加是可以折疊為一個字面常量誊稚,而且是進入常量池的。
優(yōu)化進行在編譯器編譯.java到bytecode時罗心,通過編譯器優(yōu)化后里伯,得到的效果是String a="abc" 。此時渤闷,如果字符串常量池中存在abc疾瓮,則該語句并不會創(chuàng)建對象,只是講字符串常量池中的引用返回而已飒箭。
字符串常量池存放的是對象引用狼电,不是對象蜒灰。在Java中,對象都創(chuàng)建在堆內(nèi)存中肩碟。
如果字符串常量池中不存在abc强窖,則會創(chuàng)建并放入字符串常量池,并返回引用削祈,此時會有一個對象進行創(chuàng)建翅溺。

  • String.intern()

String對象的實例調(diào)用intern方法后,可以讓JVM檢查常量池岩瘦,如果沒有實例的value屬性對應(yīng)的字符串序列比如"123"(注意是檢查字符串序列而不是檢查實例本身)未巫,就將本實例放入常量池,如果有當前實例的value屬性對應(yīng)的字符串序列"123"在常量池中存在启昧,則返回常量池中"123"對應(yīng)的實例的引用而不是當前實例的引用叙凡,即使當前實例的value也是"123"。

3.優(yōu)缺點

字符串常量池的好處就是減少相同內(nèi)容字符串的創(chuàng)建密末,節(jié)省內(nèi)存空間握爷。
如果硬要說弊端的話,就是犧牲了CPU計算時間來換空間严里。CPU計算時間主要用于在字符串常量池中查找是否有內(nèi)容相同對象的引用新啼。不過其內(nèi)部實現(xiàn)為HashTable,所以計算成本較低刹碾。

4.StringBuffer和StringBuilder

StringBuffer 始于 JDK 1.0
StringBuilder 始于 JDK 1.5
從 JDK 1.5 開始燥撞,帶有字符串變量的連接操作(+),JVM 內(nèi)部采用的是StringBuilder 來實現(xiàn)的迷帜,而之前這個操作是采用 StringBuffer 實現(xiàn)的物舒。


Paste_Image.png
Paste_Image.png

參考:
http://www.pellegrino.link/2015/08/22/string-concatenation-with-java-8.html
http://www.cnblogs.com/ITtangtang/p/3976820.html
http://www.cnblogs.com/jmzz/archive/2011/08/24/2151450.html
http://gityuan.com/2016/01/09/java-memory/
http://droidyue.com/blog/2014/08/30/java-details-string-concatenation/
http://www.reibang.com/p/380fa5c92dcc

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戏锹,隨后出現(xiàn)的幾起案子冠胯,更是在濱河造成了極大的恐慌,老刑警劉巖锦针,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荠察,死亡現(xiàn)場離奇詭異,居然都是意外死亡奈搜,警方通過查閱死者的電腦和手機悉盆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馋吗,“玉大人焕盟,你說我怎么就攤上這事『拿溃” “怎么了京髓?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長商架。 經(jīng)常有香客問我堰怨,道長,這世上最難降的妖魔是什么蛇摸? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任备图,我火速辦了婚禮,結(jié)果婚禮上赶袄,老公的妹妹穿的比我還像新娘揽涮。我一直安慰自己,他們只是感情好饿肺,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布蒋困。 她就那樣靜靜地躺著,像睡著了一般敬辣。 火紅的嫁衣襯著肌膚如雪雪标。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天溉跃,我揣著相機與錄音村刨,去河邊找鬼。 笑死撰茎,一個胖子當著我的面吹牛嵌牺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播龄糊,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼逆粹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绎签?” 一聲冷哼從身側(cè)響起枯饿,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诡必,沒想到半個月后奢方,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡爸舒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年蟋字,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扭勉。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡鹊奖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涂炎,到底是詐尸還是另有隱情忠聚,我是刑警寧澤设哗,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站两蟀,受9級特大地震影響网梢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赂毯,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一战虏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧党涕,春花似錦烦感、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骑祟,卻和暖如春回懦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背次企。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工怯晕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缸棵。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓舟茶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親堵第。 傳聞我的和親對象是個殘疾皇子吧凉,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法踏志,內(nèi)部類的語法阀捅,繼承相關(guān)的語法,異常的語法针余,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • java中String的常用方法 1饲鄙、length()字符串的長度 例:char chars[]={'a','b'...
    赤赤有名閱讀 2,027評論 0 10
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,500評論 3 93
  • 從小就喜歡藍色忍级,開始喜歡的原因很單純,只是因為上大學(xué)了伪朽,父親給我買了一個新的藍色豬豬套被轴咱。這就一眨眼蓋著我藍色豬豬...
    小笨love象閱讀 179評論 0 0
  • (一) 每到年節(jié),在外辛苦一年的人就都回到了家鄉(xiāng),同學(xué)聚會自是不可或缺的朴肺,這不窖剑,中午剛剛結(jié)束了飯局。 貪了幾杯戈稿,有...
    鄰家安心閱讀 1,374評論 37 37