【學習筆記】String、StringBuffer、StringBuilder的理解

String

String有兩種用法:

# 用法1
String a = "abc";//"abc"存在於常量池. 如果之後有String b = "abc";b也是指向常量池的"abc"
----------------------------------------------------------------------------------
# 用法2
String a = new String("abc");//"abc"存在於堆.如果之後有String b = new String("abc");b是在堆中重新開闢內存存儲"abc"

------------------------------------比較-------------------------------------------

String a = "123";
String b = "123";
String c = new String("123");
String d = new String("123");

System.out.printf(a == b);      //true   因爲比較的是變量(a、b)指向常量池的字符串的值

System.out.printf(a == c);      //false  比較的是引用,很明顯a和c的引用是不一樣的,c是後面new出來的

System.out.printf(c == d);      //false  道理差不多同上

System.out.printf(c.equals(d)); //true   比較的是引用指向的值;雖然c、d的引用不一樣,但是他們指向的值是一樣的。(這裏要明確,這倆個"123"在堆中是不同一個內存的)

String賦值的時候,先在常量池中查找有沒有當前需要的字符串,如果有,則直接指向;如果沒有,則創建一個新的字符串。

#思考字符串被創建過程

String a = "ab";
String b = "abc";
a = a + "c";
System.out.printf(a == b); //false

//這裏爲什麼  a = "abc",b ="abc"  怎麼返回false

//因爲a = a + "c";的時候,雖然a的值變爲"abc"了,但a不是指向b創建在常量池中的"abc",而是重新建了一個"abc"的對象,這兩個對象是不一樣的地址,所以返回false。

//更加細節的話,我的理解是從賦值順序來理解:
a = a + "c";   首先是a的值"ab"加上"c"組合成"abc"這個字符串,然後再存進常量池,再然後直接賦值給變量a。所以這裏不像往常那樣先查找常量池有沒有自己需要的字符串,再進行指向。

StringBuffer

StringBuffer有append()、insert()、reverse()等常用方法。

StringBuffer e = new StringBuffer("abc");
e.append("d");
System.out.print(e);            //輸出abcd
System.out.print(e.reverse());  //輸出dcba  倒序輸出
e.insert(1,"dd");               //在位置1插入dd
System.out.print(e);            //輸出addbcd

StringBuffer的值不是在常量池中,而是在堆中,因它是new出來的對象,相應的值是在對中的,引用是在棧中。

就如上面的代碼e.append("d");直接修改原來的對象中連接上新的字符串"d",而不是生成新對象。

StringBuilder

StringBuilder實際上與StringBuffer基本相似。不同的是StringBuffer是線程安全的;而StringBuilder沒有線程安全功能,但性能高於StringBuffer。(俗話說,性能安全性同於魚與熊掌不可兼得)

我們可以從其實現方法中去了解:

在實現方法中添加了synchronized,則說明給該方法加了鎖,保證線程安全。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章