java 字串原本是個很不起眼的玩意,大抵都知道他不是java的基礎資料型別 (Elementary Data Type),而是另外作為一個類存在。同時,對於java字串的相等比較,只能通過str1.equal(str2)來比較(事實證明通過 == 來比較也可以,但在實際程式中不提倡 )。這些知識,想必很多人都和我一樣。至於為什麼突然對String感興趣,來源就不說了,直接說對他的一點學習。(沒有找到相關書籍閱讀,所以只能到別的園子逛逛,然後摘抄下來。)
一,幾點常識
1、String類的源碼中定義是 public final class String ,不可被繼承。
2、在java中,所有的字串都是常量,對象的值在產生後不可以改變。給字串變數重新賦值,不過是改了引用而已。String類包含substring()一類可以返回子字串的方法,但實際上,這些方法並沒有對原來的String類的內容做任何修改,它們只是建立了另一個String類,並把它作為結果返回而已。
3、String類的本質是字元數組,public final char value[]。
String str = "abc"; 相當於 char data[]={"a","b","c"}; String str = new String(data);
4、 java對String類型重載了+操作符,可以直接使用+對兩個字串進行串連
5、運行期調用String類的intern()方法可以向String Pool中動態添加對象。當調用 intern 方法時,如果池已經包含一個等於此 String 對象的字串(該對象由 equals(Object) 方法確定),則返回池中的字串。否則,將此 String 對象添加到池中,並且返回此 String 對象的引用。
6、在程式運行時,JVM會維護兩塊不同的記憶體來維護字串資料。第一種為String Constant Pool,字串常量池,第二種為堆棧。
7、建立字串的方式有三種:
String str1 = "abc";String str2 = new String("abc");String str3 = str1+"cde";
二,深入String 的建立("abc "在編譯期建立,new String("abc") 在運行期確定)
原理1:當使用任何方式來建立一個字串對象s時,Java運行時(運行中JVM)會在String池中找是否存在內容相同的字串對象,如果不存在,則在池中建立一個字串s,否則,不在池中添加。 原理2:Java中,只要使用new關鍵字來建立對象,則一定會在堆棧區建立一個新的對象。 原理3:使用直接指定(String str="abc")或者使用純字串串聯( String str="ab"+"cd" )來建立String對象,則僅僅會檢查維護String池中的字串,如果池中存在相同內容的對象,則不會在池中建立;否則,就在池中建立一個字串對象。這種方式不管是否存在都不會在堆棧中建立對象。 原理4:使用包含變數的運算式(String str="ab"+str1)來建立String對象,則不僅會檢查維護String池,而且還會在堆棧區建立一個String對象(不管是否在堆棧區存在相同內容的對象)。
三,字串拼接(轉載自http://blog.csdn.net/izard999/article/details/6708433)
首先看一段代碼
String str = null;str = str + "abc";System.out.pprinltn(str); // "nullabc"
很驚訝是吧。看看解釋吧:
str1+str2:
運行時, 兩個字串str1, str2的拼接首先會調用 String.valueOf(obj),這個Obj為str1,而String.valueOf(Obj)中的實現是return obj == null ? "null" : obj.toString(), 然後產生StringBuilder, 調用的StringBuilder(str1)構造方法, 把StringBuilder初始化,長度為str1.length()+16,並且調用append(str1)!
接下來調用StringBuilder.append(str2), 把第二個字串拼接進去, 然後調用StringBuilder.toString返回結果!
所以那道題答案的由來就是StringBuilder.append("null").append("abc").toString();
很自然的,下面的結果就不足為奇了:
String str = nullstr = str + null; // "nullnull"
四,字串的空值與null
String str = new String(); // 初始化一個新建立的 String
對象,使其表示一個Null 字元序列。即為 str="";
String a = new String();a=a+null; //"null"
五,關於字串的比較
== 比較字串的儲存空間地址,或者說引用
equal() 比較字串的內容的值
六,一些程式
public static void main(String[] args) {//在變數池和堆中分別建立對象“abc”,s1指向堆中對象String s1 = new String("abc");//在堆中建立對象“abc”,s2指向堆中對象String s2 = new String("abc");//s3直接指向堆中對象String s3 = "abc";//在池中建立對象"a",s4指向該對象String s4 = "a";//在池中建立對象“bc”,在堆中建立對象“abc”,並且s5指向堆中對象String s5 = s4 + "bc";//在池中建立對象“ab”和“c”,s6指向池中對象"abc"String s6 = "ab" + "c";System.out.println(s1 == s2); //falseSystem.out.println(s1 == s3); //falseSystem.out.println(s2 == s3); //falseSystem.out.println(s1.intern() == s3); //trueSystem.out.println(s3 == s5); //falseSystem.out.println(s3 == s6); //true}
還有幾個經常考的面試題:
1.
String s1 =
new String("s1") ;
String s2 =
new String("s1") ;
上面建立了幾個String對象?
答案:3個 ,編譯期Constant Pool中建立1個,運行期heap中建立2個.
2.
String s1 =
"s1";
String s2 = s1;
s2 =
"s2";
s1指向的對象中的字串是什麼?
答案: "s1"