字串的內部儲存原理
字串的儲存
字串是一個字面量,它的值儲存在常量池中(也就是方法區的執行時常量池),他的底層是使用字元陣列來儲存,它是可以共享的。以下展示直接字串與字串物件的儲存。
其中String s1 = “ab”;會產生一個物件,也就是它底層的字元陣列。
單獨的String s2 = new String(“ab”);是會產生兩個物件的,也就是堆記憶體中new出來的物件,和字元陣列。
如果兩個同時建立則只會產生兩個物件,也就是字元陣列和堆記憶體中new出來的物件。至於方法區的常量池中的字面量和字元陣列會共享。
字串的拼接
public class StringDemo1 { public static void main(String[] args) { // String s1 = "abc"; // s1 = "def"; // 指向常量池 String s1 = "ab"; // 指向堆記憶體 String s2 = new String("ab"); // "a"和"b"是兩個字面量 // 兩個字面量在運算的時候為了提高效率,在編譯的時候會進行自動的計算優化 // byte b = 3 + 5; -> byte b = 8; // String s3 = "ab"; String s3 = "a" + "b"; // 字串在使用+拼接的時候底層實際上是呼叫了StringBuilder中的append方法 String s4 = "a"; // s4 = new StringBuilder(s4).append("b").toString(); // s4 = new String("ab"); s4 = s4 + "b"; System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s1 == s4); System.out.println(s2 == s4); } }
這裡需要注意幾個點:
①兩個字面量在運算的時候為了提高效率,在編譯的時候會進行自動的計算優化。也就是在寫出String str = “a” + “b”; 和String str = “ab”;的編譯完成時的效果是一樣的。
②當以new的形式去建立一個字串的時候,指標直接指向的地址是堆記憶體中的地址。
③當變數和常量進行相加的時候是不會再編譯期自動運算的。而是建立一個StringBuilder然後在後面追加一個字串,然後再new一個新的對向也就是它的toString方法。最後指向的是這個toString之後所new的物件。
這裡就詳細說明一下字串的拼接步驟如下:
String str = “a”;
String str1 = “b”;
str = str + str1;
①new StringBuilder(“a”); // 這時會產生一個新的物件
②.append(“b”);// append完成之後就又會產生一個物件
③.toString();// 這時會new一個String的物件。
前前後後涉及到了5個物件也就是拼接好一次需要多產生3個物件。
那麼這個過程直接用StringBuilder的append呢?
也就是上述過程的②③步驟,會多產生2個物件。需要注意的是StringBuilder只是在最後一次toString一把而在使用+的時候每次連線都會toString一把。