String纫溃、StringBuffer和StringBuilder的區(qū)別

類繼承關(guān)系中圖

類繼承關(guān)系圖

特點

String

來看幾個例子

String s1 = "hello world";
String s2 = "hello world";
System.out.println(s1 == s2);

輸出結(jié)果是true

String s1 = new String("hello world");
String s2 = new String("hello world");
String s3 = "hello world";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));

輸出結(jié)果是 false沪羔、true巍沙、true

在 Java 編譯好的 class 文件中葵姥,有個區(qū)域被稱為常量池(Constant Pool),存儲著各種常量赎瞎,其中存儲字符串常量的區(qū)域被習慣地稱為字符串池(String Pool)牌里。在第一個例子中,有兩個“hello world”常量务甥,但是在常量池中牡辽,只會創(chuàng)建一個常量,也就是說敞临,在編譯好的 class 文件中态辛,只能找到一個“hello world”常量。因此 s1 和 s2 指向的在常量池中同一個字符串對象挺尿,“==”比較是否是同一個對象奏黑,所以結(jié)果返回 true炊邦。

擴展知識

private final char value[];

字符串是用一個不可變的字符數(shù)組來存儲字符串內(nèi)容,當 String 對象創(chuàng)建之后熟史,就不能修改對象中存儲的內(nèi)容馁害,所以說,String 類型是不可變的(immutable)
例如

String s1 = new String("hello");
s1 = s1 + " world";

因為 String 是不可變的蹂匹,這段代碼會根據(jù)s1的內(nèi)容和字符串常量“ world”在heap區(qū)創(chuàng)建一個新的字符串

String s1 = new String("hello world");

該語句創(chuàng)建兩個 String 對象碘菜,一個是在編譯時,創(chuàng)建于字符串常量區(qū)限寞,一個是在運行時忍啸,創(chuàng)建于heap區(qū)。

Java對String進行了“+”操作符重載履植,利用“+”可以將字符串連接计雌。但是需要注意的是

String s1 = "hello" + " world";

該代碼與第一點的例子不一樣,編譯時編譯器會直接提取兩個常量的內(nèi)容玫霎,只生成“hello world”一個字符串凿滤,同理,無論多少個常量相加鼠渺,都是生成一個對象鸭巴。

運行時調(diào)用 String 的 intern() 方法可以向 String Pool 中動態(tài)添加對象。

5.String創(chuàng)建的幾種方法

  1. 使用“”拦盹。
  2. 使用 new String();
  3. 使用 new String("hello world");
  4. 使用重載操作符“+”

StringBuffer&StringBuilder

StringBuilder一個可變的字符序列是5.0新增的鹃祖。此類提供一個與 StringBuffer 兼容的 API,但不保證同步普舆。該類被設(shè)計用作 StringBuffer 的一個簡易替換恬口,用在字符串緩沖區(qū)被單個線程使用的時候(這種情況很普遍)。如果可能沼侣,建議優(yōu)先采用該類祖能,因為在大多數(shù)實現(xiàn)中,它比 StringBuffer 要快蛾洛。
Stringbuffer 和 StringBuilder除了線程安全的區(qū)別外养铸,其他基本一致,都繼承于AbstractStringBuffer轧膘。
來看一下AbstractStringBuffer的源碼

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;

    /**
     * This no-arg constructor is necessary for serialization of subclasses.
     */
    AbstractStringBuilder() {
    }

    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

    /**
     * Returns the length (character count).
     *
     * @return  the length of the sequence of characters currently
     *          represented by this object
     */
    @Override
    public int length() {
        return count;
    }

    /**
     * Returns the current capacity. The capacity is the amount of storage
     * available for newly inserted characters, beyond which an allocation
     * will occur.
     *
     * @return  the current capacity
     */
    public int capacity() {
        return value.length;
    }

AbstractStringBuffer 使用的是可變的char數(shù)組钞螟,在創(chuàng)建 StringBuffer 和 StringBuilder 時有幾種方式,其中無參的構(gòu)造方法調(diào)用的是父類的構(gòu)造方法谎碍,創(chuàng)建大小為16的char數(shù)組

public StringBuffer() {
    super(16);
}

public StringBuilder() {
    super(16);
}

其他的構(gòu)造方法鳞滨,StringBuilder 與之類似

public StringBuffer(int capacity) {
    super(capacity);
}

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuffer(CharSequence seq) {
    this(seq.length() + 16);
    append(seq);
}

其他常見方法:appendinsert


三者區(qū)別

可變性

String 不可變蟆淀,StringBuffer拯啦、StringBuilder可變

速度

StringBuilder > StringBuffer > String

線程安全

String澡匪、StringBuilder不安全,StringBuffer安全


總結(jié)

  1. 在編譯階段就能夠確定的字符串常量褒链,完全沒有必要創(chuàng)建String或StringBuffer對象唁情。直接使用字符串常量的"+"連接操作效率最高。
  2. StringBuffer對象的append效率要高于String對象的"+"連接操作碱蒙。
  3. 不停的創(chuàng)建對象是程序低效的一個重要原因荠瘪。那么相同的字符串值能否在堆中只創(chuàng)建一個String對象那。顯然拘留字符串能夠做到這一點赛惩,除了程序中的字符串常量會被JVM自動創(chuàng)建拘留字符串之外,調(diào)用String的intern()方法也能做到這一點趁餐。當調(diào)用intern()時喷兼,如果常量池中已經(jīng)有了當前String的值,那么返回這個常量指向拘留對象的地址后雷。如果沒有季惯,則將String值加入常量池中,并創(chuàng)建一個新的拘留字符串對象臀突。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勉抓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子候学,更是在濱河造成了極大的恐慌藕筋,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梳码,死亡現(xiàn)場離奇詭異隐圾,居然都是意外死亡,警方通過查閱死者的電腦和手機掰茶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門暇藏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人濒蒋,你說我怎么就攤上這事盐碱。” “怎么了沪伙?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵瓮顽,是天一觀的道長。 經(jīng)常有香客問我焰坪,道長趣倾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任某饰,我火速辦了婚禮儒恋,結(jié)果婚禮上善绎,老公的妹妹穿的比我還像新娘。我一直安慰自己诫尽,他們只是感情好禀酱,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著牧嫉,像睡著了一般剂跟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酣藻,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天曹洽,我揣著相機與錄音,去河邊找鬼辽剧。 笑死送淆,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的怕轿。 我是一名探鬼主播偷崩,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼撞羽!你這毒婦竟也來了阐斜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤诀紊,失蹤者是張志新(化名)和其女友劉穎谒出,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渡紫,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡到推,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了惕澎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莉测。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唧喉,靈堂內(nèi)的尸體忽然破棺而出捣卤,到底是詐尸還是另有隱情,我是刑警寧澤八孝,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布董朝,位于F島的核電站,受9級特大地震影響干跛,放射性物質(zhì)發(fā)生泄漏子姜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一楼入、第九天 我趴在偏房一處隱蔽的房頂上張望哥捕。 院中可真熱鬧牧抽,春花似錦、人聲如沸遥赚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凫佛。三九已至讲坎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愧薛,已是汗流浹背晨炕。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毫炉,地道東北人府瞄。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像碘箍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鲸郊,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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