淺談java中的String

第一茧痕,簡介

????????String是java語言非尘淇基礎(chǔ)和重要的類丹墨,提供了構(gòu)造和管理字符串的各種基本邏輯廊遍。它是典型的immutable類,被聲明成為final class贩挣,所有屬性也都是final的喉前。也由于它的不可變性,類似拼接王财,裁剪字符串等動作卵迂,都會產(chǎn)生新的String對象。String特性主要有兩點绒净。1见咒,不可變:不可變的主要作用在于當一個對象需要被多線程共享,并且訪問頻繁時挂疆,可以省略同步和鎖等待的時間改览,從而大幅度提高系統(tǒng)性能。不可變模式是一個可以提高多線程程序的性能缤言,降低多線程程序復(fù)雜度的設(shè)計模式宝当。2,常量池的優(yōu)化:當2個String對象擁有相同的值時胆萧,他們只引用常量池中的同一個拷貝庆揩。當同一個字符串反復(fù)出現(xiàn)時,這個技術(shù)可以大幅度節(jié)省內(nèi)存空間跌穗。

????????StringBuffer是為了解決String拼接產(chǎn)生太多中間對象的問題而提供的一個類订晌。StringBuffer本質(zhì)是一個線程安全的可修改字符串序列,它保證了線程安全蚌吸,也隨之帶來了額外的性能開銷锈拨。

????????StringBuild是jdk1.5中新增的,在能力上和StringBuffer沒有本質(zhì)區(qū)別套利,但是它去掉了線程安全的部分推励,有效減小了開銷鹤耍。

????????為了實現(xiàn)修改字符串序列的目的,StringBuffer和StringBuild底層都是利用了可修改的(char,JDK9以后是byte)數(shù)組验辞,二者都繼承了AbstractStringBuilder,里面包含了基本操作稿黄,區(qū)別僅在于最終方法是否加了synchronized。它們內(nèi)部構(gòu)建初始化數(shù)組長度是16跌造,長度大于16時會自動擴容杆怕,需要拋棄原有數(shù)據(jù)創(chuàng)建新(可以簡單認為是倍數(shù))的數(shù)組,還要進行arraycopy壳贪。所以我們可以根據(jù)字符長度傳入初始化的合適長度陵珍,避免多次擴容的開銷。除非有線程安全考慮建議使用StringBuild违施。

第二互纯,String的創(chuàng)建機理和應(yīng)用場景

? ? ? ? 創(chuàng)建機理:由于String在Java世界中使用過于頻繁,Java為了避免在一個系統(tǒng)中產(chǎn)生大量的String對象磕蒲,引入了字符串常量池留潦。其運行機制是:創(chuàng)建一個字符串時,首先檢查池中是否有值相同的字符串對象辣往,如果有則不需要創(chuàng)建直接從池中剛查找到的對象引用兔院;如果沒有則新建字符串對象,返回對象引用站削,并且將新創(chuàng)建的對象放入池中坊萝。但是,通過new方法創(chuàng)建的String對象是不檢查字符串池的许起,而是直接在堆區(qū)或棧區(qū)創(chuàng)建一個新的對象十偶,也不會把對象放入池中。上述原則只適用于通過直接量給String對象引用賦值的情況街氢。舉例:

? ? ? ? String str1 = "hello,world"; //通過直接量賦值方式扯键,放入字符串常量池睦袖。

? ? ? ? String str2 = new String(“hello,world”);//通過new方式賦值方式珊肃,不放入字符串常量池。

????????注意:String提供了inter()方法馅笙。調(diào)用該方法時伦乔,如果常量池中包括了一個等于此String對象的字符串(由equals方法確定),則返回池中的字符串董习。否則烈和,將此String對象添加到池中,并且返回此池中對象的引用皿淋。

? ??????應(yīng)用場景:在字符串內(nèi)容不經(jīng)常發(fā)生變化的業(yè)務(wù)場景優(yōu)先使用String類招刹。例如:常量聲明恬试、少量的字符串拼接操作等。如果有大量的字符串內(nèi)容拼接疯暑,避免使用String與String之間的“+”操作训柴,因為這樣會產(chǎn)生大量無用的中間對象,耗費空間且執(zhí)行效率低下(新建對象妇拯、回收對象花費大量時間)幻馁。

第三,輕松理解String.intern()

????????該方法的總結(jié)參考《深入理解Java虛擬機》一書越锈。

????????1仗嗦,new String都是在堆上創(chuàng)建字符串對象。當調(diào)用 intern() 方法時甘凭,編譯器會將字符串添加到常量池中(stringTable維護)稀拐,并返回指向該常量的引用。?JDK1.8后字符串常量池放到了堆中丹弱,不再是在方法區(qū)中了钩蚊。


????????2,通過字面量賦值創(chuàng)建字符串(如:String str=”twm”)時蹈矮,會先在常量池中查找是否存在相同的字符串砰逻,若存在,則將棧中的引用直接指向該字符串泛鸟;若不存在蝠咆,則在常量池中生成一個字符串,再將棧中的引用指向該字符串北滥。

????????3刚操,常量字符串的“+”操作,編譯階段直接會合成為一個字符串再芋。如string str=”JA”+”VA”菊霜,在編譯階段會直接合并成語句String str=”JAVA”,于是會去常量池中查找是否存在”JAVA”,從而進行創(chuàng)建或引用济赎。

????????4鉴逞,對于final字段,編譯期直接進行了常量替換(而對于非final字段則是在運行期進行賦值處理的)司训。

在編譯時构捡,直接替換成了String str3=”ja”+”va”,根據(jù)第三條規(guī)則壳猜,再次替換成String str3=”JAVA”

????????5勾徽,常量字符串和變量拼接時(如:String str3=baseStr + “01”;)會調(diào)用stringBuilder.append()在堆上創(chuàng)建新的對象。

????????6统扳,JDK 1.7后喘帚,intern方法還是會先去查詢常量池中是否有已經(jīng)存在畅姊,如果存在,則返回常量池中的引用吹由,這一點與之前沒有區(qū)別涡匀,區(qū)別在于,如果在常量池找不到對應(yīng)的字符串溉知,則不會再將字符串拷貝到常量池陨瘩,而只是在常量池中生成一個對原字符串的引用。簡單的說级乍,就是往常量池放的東西變了:原來在常量池中找不到時舌劳,復(fù)制一個副本放到常量池,1.7后則是將在堆上的地址引用復(fù)制到常量池玫荣。

舉例說明:

str1 == str2返回true甚淡,str3 == str4返回false

第四,String使用equals和==比較的區(qū)別捅厂?

????????“==”操作符的作用:1贯卦,用于基本數(shù)據(jù)類型的比較。2焙贷,判斷引用是否指向堆內(nèi)存的同一塊地址撵割。

????????equals的作用:用于判斷兩個變量是否是對同一個對象的引用,即堆中的內(nèi)容是否相同辙芍,返回值為布爾類型

????????結(jié)論:1啡彬,對象不同,內(nèi)容相同故硅,"=="返回false庶灿,equals返回true。2吃衅,同一對象往踢,"=="和equals結(jié)果相同

str2 == str1返回false,str2.equals(str1)返回true


我是溫馭臣徘层,一個Android開發(fā)者峻呕,以上是我的簡單總結(jié),如果有缺陷惑灵,希望在評論區(qū)看到您的補充山上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市英支,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哮伟,老刑警劉巖干花,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妄帘,死亡現(xiàn)場離奇詭異,居然都是意外死亡池凄,警方通過查閱死者的電腦和手機抡驼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肿仑,“玉大人致盟,你說我怎么就攤上這事∮任浚” “怎么了馏锡?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伟端。 經(jīng)常有香客問我杯道,道長,這世上最難降的妖魔是什么责蝠? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任党巾,我火速辦了婚禮,結(jié)果婚禮上霜医,老公的妹妹穿的比我還像新娘齿拂。我一直安慰自己,他們只是感情好肴敛,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布创肥。 她就那樣靜靜地躺著,像睡著了一般值朋。 火紅的嫁衣襯著肌膚如雪叹侄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天昨登,我揣著相機與錄音趾代,去河邊找鬼。 笑死丰辣,一個胖子當著我的面吹牛撒强,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笙什,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼飘哨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了琐凭?” 一聲冷哼從身側(cè)響起芽隆,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胚吁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牙躺,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年腕扶,在試婚紗的時候發(fā)現(xiàn)自己被綠了孽拷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡半抱,死狀恐怖脓恕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窿侈,我是刑警寧澤炼幔,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站棉磨,受9級特大地震影響江掩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乘瓤,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一环形、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衙傀,春花似錦抬吟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至聪建,卻和暖如春钙畔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背金麸。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工擎析, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挥下。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓揍魂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親棚瘟。 傳聞我的和親對象是個殘疾皇子现斋,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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