Java剖析String類

String類對象的兩種實例化方法

String并不是一個基本數(shù)據(jù)類型,它本身屬于一個類。但是這個類在設計的過程之中加入了屬于Java的特殊支持,所以對于這個類的對象實例化方式有兩種形式

  • 直接賦值:String 對象名稱 = "內容";
  • 構造方法:String 對象名稱 = new String("內容");

String的相等比較

如果說現(xiàn)在有兩個int型的變量,要進行相等的判斷汽馋,則直接使用“==”即可;如果進行String的比較午笛,我們可先用“=="嘗試:

class StringDemo{
    public static void main(String[] args){
        String steA = "hello";
        String steB = new String("hello") ;
        String steC = steB;
        System.out.println(steA == steB);//false
        System.out.println(steB == steC);//true
        System.out.println(steA == steC);//false
    }
}

發(fā)現(xiàn)結果并不相等惭蟋,此時我們發(fā)現(xiàn)問題苗桂,字符串的內容實際上都是一樣的药磺,而在使用“==”比較結果是\color{red}{flase},具體原因如下圖所示:

String內存關系圖

  • 發(fā)現(xiàn)在程序中如果使用“==”比較的只是兩個對象(任意的引用類型)\color{red}{堆內存的地址數(shù)值},并不是對堆內存中保存的內容進行比較
  • 如果想要在String類中進行比較煤伟,那么可以利用String類中提供的public boolean equals(String str);方法進行比較
代碼如下:
class StringDemo{
    public static void main(String[] args){
        String strA = "hello";
        String strB = new String("hello") ;
        String strC = strB;
        System.out.println(strA.equals(strB));//true
        System.out.println(strB.equals(strC));//true
        System.out.println(strA.equals(strC));//true
    }
}

\color{red}{由于內容是可控的因素而地址是不可控的因素癌佩,因此只要是字符串的比較都使用equals()完成}

面試題:請解釋在String比較中”==“與"equals()"的區(qū)別
  • "=="是java的一種關系運算符,可以進行數(shù)值比較便锨,如果用在String上時則是對堆內存地址數(shù)值進行比較围辙,使得結果錯誤
  • "equals()"是String類的一個方法,用于進行字符串內容的比較

String匿名對象

任何的編程語言都不會提供有字符串這一數(shù)據(jù)類型放案,字符串的描述在很多語言之中都是用字符數(shù)組表示姚建,而在Java的設計之初為了解決這樣的問題,專門提供了一個String類來進行描述吱殉。但是隨著發(fā)展掸冤,為了能夠讓程序變得更加的易于開發(fā),所以在Java里面也提供雙引號聲明的數(shù)據(jù)友雳,而這些數(shù)據(jù)稿湿,在Java中并不是普通的變量,而是String類的匿名對象

String 字符串對象 = "字符串";本質:就是為一個字符串的匿名對象起了一個名字


String類兩種實例化對象的區(qū)別(核心)

此時對于String類的聲明方式有兩種押赊,那么這兩種方式到底應該使用哪一種饺藤,以及每種方式的區(qū)別

分析String類對象直接實例化的形式

開辟一塊堆內存空間,并且開辟一塊棧內存空間將直接指向該堆內存

觀察以下代碼:

class StringDemo{
    public static void main(String[] args){
        String strA = "hello";
        String strB = "hello";
        String strC = "nihao";
        System.out.println(strA == strB);//true
        System.out.println(strB == strC);//false
        System.out.println(strA == strC);//false
    }
}

\color{red}{此時我們可能有疑問,為何使用"=="運算關系符strA仍然與strB相等涕俗,在接下來我們會得到這個答案}
內存關系圖如下:

內存關系圖

關于對象池的概念(Object Pool):

  • 為了更方便用戶的代碼編寫開發(fā)罗丰,針對于幾個特殊的類使用了共享設計的思路,其中String類屬于這其中的一員咽袜。這種設計思路是Java自己的支持丸卷,而且只針對于直接賦值的情況

  • 在使用直接賦值實例化String類對象的操作之中,字符串的內容定義之后實際上會自動將其保存在一個對象池之中询刹,而后如果現(xiàn)在有其他的字符串對象也采用了直接賦值的形式谜嫉,并且內容與之前的字符串內容完全相同,那么不會開辟新的堆內存空間凹联,而是會通過對象池找到已有的堆內存空間地址沐兰,直接引用即可

回到上方的疑問:由于對象池的存在,當若干個字符內容相同時蔽挠,地址是完全相同的住闯,所以“==“的結果也是相同的,這樣的設計就是共享設計模式

分析String類利用構造方法實例化對象的形式

代碼如下:

class StringDemo{
    public static void main(String[] args){
        String str = new String("hello");
        System.out.println(str);
    }
}

內存關系圖如下:

內存關系圖

分析以上情況:

  • 通過此時的內存分析可以發(fā)現(xiàn)澳淑,如果采用了構造方法進行String類對象的實例化操作比原,那么最終會產生兩塊堆內存,其中一塊是垃圾空間

  • 如果使用了構造方法進行String類對象實例化杠巡,那么所產生的的對象將不會保存在對象池之中(此對象無法重用)量窘,如果用戶需要其入池,只能通過public String intern();手工入池

面試題:請解釋String類兩種對象實例化的區(qū)別
  • 直接賦值String str = "字符串";:只會開辟一塊堆內存氢拥,且對象可以自動入池以供重復使用

  • 構造方法String str = new String("字符串");:會開辟兩塊堆內存蚌铜,且其中一塊為垃圾空間,由構造方法聲明的實例化對象不能自動入池嫩海,需要調用intern()方法手動入池


字符串一旦聲明不可改變

觀察以下代碼:

class StringDemo{
    public static void main(String[] args){
        String str = "hello ";
        str += "world";
        str += "!!!";
        System.out.println(str);
    }
}

分析內存關系:

內存關系圖

可以發(fā)現(xiàn)整個的操作流程之中冬殃,都是String類對象的引用發(fā)生著改變,而字符串本身的內容并沒有改變叁怪,這樣的操作會產生大量垃圾审葬,因此杜絕使用


總結

  • String類開發(fā)中都使用直接賦值,并且不要頻繁修改

  • 字符串內容比較時使用equals()方法

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末奕谭,一起剝皮案震驚了整個濱河市涣觉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌展箱,老刑警劉巖旨枯,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異混驰,居然都是意外死亡攀隔,警方通過查閱死者的電腦和手機皂贩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門钥勋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厨幻,“玉大人拴竹,你說我怎么就攤上這事俊抵。” “怎么了赏枚?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵瓶蝴,是天一觀的道長孝偎。 經常有香客問我映皆,道長挤聘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任捅彻,我火速辦了婚禮组去,結果婚禮上,老公的妹妹穿的比我還像新娘步淹。我一直安慰自己从隆,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布缭裆。 她就那樣靜靜地躺著键闺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澈驼。 梳的紋絲不亂的頭發(fā)上辛燥,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音盅藻,去河邊找鬼购桑。 笑死畅铭,一個胖子當著我的面吹牛氏淑,可吹牛的內容都是我干的。 我是一名探鬼主播硕噩,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼假残,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炉擅?” 一聲冷哼從身側響起辉懒,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谍失,沒想到半個月后眶俩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡快鱼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年颠印,在試婚紗的時候發(fā)現(xiàn)自己被綠了纲岭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡线罕,死狀恐怖止潮,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情钞楼,我是刑警寧澤喇闸,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站询件,受9級特大地震影響燃乍,放射性物質發(fā)生泄漏。R本人自食惡果不足惜宛琅,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一橘沥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夯秃,春花似錦座咆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至色建,卻和暖如春哺呜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背箕戳。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工某残, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陵吸。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓玻墅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壮虫。 傳聞我的和親對象是個殘疾皇子澳厢,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章囚似,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,771評論 2 9
  • 一剩拢、String 類 1、定義: 1饶唤、從概念上講徐伐,java字符串就是Unicode字符序列。每個用雙引號括起來的字...
    玉圣閱讀 1,581評論 0 1
  • 前言 RTFSC (Read the fucking source code )才是生活中最重要的募狂。我們天天就是要...
    二毛_coder閱讀 457評論 1 1
  • 在編寫程序的過程中办素,不了避免的要用到字符串魏保,所以String類的常用方法的用法是必須掌握的。學習一個類的使用方法最...
    Geg_Wuz閱讀 1,272評論 0 4
  • 所有知識點已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)摸屠? 在 Jav...
    侯蛋蛋_閱讀 2,453評論 1 4