JavaSE知識點11java深探String酸纲、StringBuilder以及StringBuffer

你了解String類嗎捣鲸?

  • 1 想要了解一個類,最好的辦法就是看這個類的實現(xiàn)源代碼
    String類的定義如下:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    private final char value[];
    private final int offset;
    private final int count;
    private int hash;
    private static final long serialVersionUID = -6849794470754667710L;
    ....
}
  • 1 String類是final類闽坡,也即意味著String類不能被繼承栽惶,并且它的屬性和方法都默認(rèn)為final方法。
  • 2 String類其實是通過char數(shù)組來保存字符串的疾嗅。
  • 3 下面再繼續(xù)看String類的一些方法實現(xiàn)
public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
    }
 
 public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    char buf[] = new char[count + otherLen];
    getChars(0, count, buf, 0);
    str.getChars(0, otherLen, buf, count);
    return new String(0, count + otherLen, buf);
    }
 
 public String replace(char oldChar, char newChar) {
    if (oldChar != newChar) {
        int len = count;
        int i = -1;
        char[] val = value; /* avoid getfield opcode */
        int off = offset;   /* avoid getfield opcode */
 
        while (++i < len) {
        if (val[off + i] == oldChar) {
            break;
        }
        }
        if (i < len) {
        char buf[] = new char[len];
        for (int j = 0 ; j < i ; j++) {
            buf[j] = val[off+j];
        }
        while (i < len) {
            char c = val[off + i];
            buf[i] = (c == oldChar) ? newChar : c;
            i++;
        }
        return new String(0, len, buf);
        }
    }
    return this;

從上面的三個方法可以看出外厂,無論是substring、concat還是replace操作都不是在原有的字符串上進(jìn)行的代承,而是重新生成了一個新的字符串對象汁蝶。也就是說進(jìn)行這些操作后,最原始的字符串并沒有被改變论悴。

  • 5 對String對象的任何改變都不影響到原對象掖棉,相關(guān)的任何change操作都會生成新的對象。

深入理解String膀估、StringBuffer幔亥、StringBuilder

  • 1 String str="hello world"和String str=new String("hello world")的區(qū)別
public class MyTest{
    public static void main(String[] args) {
        String str1 = "hello world";
        String str2 = new String("hello world");
        String str3 = "hello world";
        String str4 = new String("hello world");
         
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str2==str4);
    }
}

輸出結(jié)果為:

false
true
false

1)在class文件中有一部分 來存儲編譯期間生成的 字面常量以及符號引用,這部分叫做class文件常量池察纯,在運(yùn)行期間對應(yīng)著方法區(qū)的運(yùn)行時常量池帕棉。
2)因此在上述代碼中,String str1 = "hello world";和String str3 = "hello world"; 都在編譯期間生成了 字面常量和符號引用捐寥,運(yùn)行期間字面常量"hello world"被存儲在運(yùn)行時常量池(當(dāng)然只保存了一份)笤昨。通過這種方式來將String對象跟引用綁定的話,JVM執(zhí)行引擎會先在運(yùn)行時常量池查找是否存在相同的字面常量握恳,如果存在瞒窒,則直接將引用指向已經(jīng)存在的字面常量;否則在運(yùn)行時常量池開辟一個空間來存儲該字面常量乡洼,并將引用指向該字面常量崇裁。
3)總所周知,通過new關(guān)鍵字來生成對象是在堆區(qū)進(jìn)行的束昵,而在堆區(qū)進(jìn)行對象生成的過程是不會去檢測該對象是否已經(jīng)存在的拔稳。因此通過new來創(chuàng)建對象,創(chuàng)建出的一定是不同的對象锹雏,即使字符串的內(nèi)容是相同的巴比。

  • 2 String、StringBuffer以及StringBuilder的區(qū)別
    1)既然在Java中已經(jīng)存在了String類,那為什么還需要StringBuilder和StringBuffer類呢轻绞?
    那么看下面這段代碼:
public class MyTest{
    public static void main(String[] args) {
        String string = "";
        for(int i=0;i<10000;i++){
            string += "hello";
        }
    }
}

這句 string += "hello";的過程相當(dāng)于將原有的string變量指向的對象內(nèi)容取出與"hello"作字符串相加操作再存進(jìn)另一個新的String對象當(dāng)中采记,再讓string變量指向新生成的對象。
2)再看下面這段代碼:

public class MyTest {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i=0;i<10000;i++){
            stringBuilder.append("hello");
        }
    }
}

只生成了一個對象政勃,append操作是在原有對象的基礎(chǔ)上進(jìn)行的唧龄。因此在循環(huán)了10000次之后,這段代碼所占的資源要比上面小得多奸远。
3)那么有人會問既然有了StringBuilder類既棺,為什么還需要StringBuffer類?
查看源代碼便一目了然懒叛,事實上丸冕,StringBuilder和StringBuffer類擁有的成員屬性以及成員方法基本相同,區(qū)別是StringBuffer類的成員方法前面多了一個關(guān)鍵字:synchronized芍瑞,不用多說晨仑,這個關(guān)鍵字是在多線程訪問時起到安全保護(hù)作用的,也就是說StringBuffer是線程安全的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拆檬,一起剝皮案震驚了整個濱河市洪己,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌竟贯,老刑警劉巖答捕,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異屑那,居然都是意外死亡拱镐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門持际,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沃琅,“玉大人,你說我怎么就攤上這事蜘欲∫婷迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵姥份,是天一觀的道長郭脂。 經(jīng)常有香客問我,道長澈歉,這世上最難降的妖魔是什么展鸡? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮埃难,結(jié)果婚禮上莹弊,老公的妹妹穿的比我還像新娘涤久。我一直安慰自己,他們只是感情好箱硕,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布拴竹。 她就那樣靜靜地躺著,像睡著了一般剧罩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上座泳,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天惠昔,我揣著相機(jī)與錄音,去河邊找鬼挑势。 笑死镇防,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的潮饱。 我是一名探鬼主播来氧,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼香拉!你這毒婦竟也來了啦扬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凫碌,失蹤者是張志新(化名)和其女友劉穎扑毡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盛险,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡瞄摊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苦掘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片换帜。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鹤啡,靈堂內(nèi)的尸體忽然破棺而出惯驼,到底是詐尸還是另有隱情,我是刑警寧澤揉忘,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布跳座,位于F島的核電站,受9級特大地震影響泣矛,放射性物質(zhì)發(fā)生泄漏疲眷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一您朽、第九天 我趴在偏房一處隱蔽的房頂上張望狂丝。 院中可真熱鬧换淆,春花似錦、人聲如沸几颜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛋哭。三九已至县习,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谆趾,已是汗流浹背躁愿。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留沪蓬,地道東北人彤钟。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像跷叉,于是被迫代替她去往敵國和親逸雹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法云挟,類相關(guān)的語法梆砸,內(nèi)部類的語法,繼承相關(guān)的語法植锉,異常的語法辫樱,線程的語...
    子非魚_t_閱讀 31,632評論 18 399
  • java中String的常用方法 1、length()字符串的長度 例:char chars[]={'a','b'...
    赤赤有名閱讀 2,053評論 0 10
  • final關(guān)鍵字(最終) final修飾的類無法被繼承. final修飾的方法無法被覆蓋. final修飾的局部變...
    yangliangliang閱讀 694評論 0 0
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗俊庇。 張土汪:刷leetcod...
    土汪閱讀 12,745評論 0 33
  • 讀徐公子勝治的《神游》狮暑。讀到“入妄”“破妄”一卷,心有所感辉饱。 創(chuàng)業(yè)如修行搬男。我一直在創(chuàng)業(yè),自然曾經(jīng)入妄彭沼。也許現(xiàn)在也在...
    寫作喚醒教練一一葉小問閱讀 968評論 1 1