String, StringBuffer, StringBuilder整理

Class

String

StringBuffer

StringBuilder

內容能改變?

       

§ String

    在Java中String有許多特性,我整理了一些我認為特別的。

  1. String不允許字串內容改變

    換句話來說,當你給定字串之後,該字串變數永遠不變(immutable)。Java為了改進C的字串容易超出陣列邊界,造成不可預期錯誤,因而規定這樣。如果你硬要修改,它會建立一個新字串空間讓你存放,以確保遵守這項規定

  - 舉例來說:

/*------------------------------------------------------------
    這個程式是要測試及表明,String在Java的內容永遠不變。
------------------------------------------------------------*/

public class String_Test01{
    public static void main(String[] args){
        String s1 = new String("abc");
        String s2 = s1;
        System.out.println("s1: " + s1 + ", s2: " + s2);
        System.out.println("s1 and s2 is point to same memory: " + (s1==s2));
        
        s1 += "de";
        System.out.println("After s1 += \"de\";");
        System.out.println("s1: " + s1 + ", s2: " + s2);
        System.out.println("s1 and s2 is point to same memory: " + (s1==s2));
    }
}

  - 輸出結果:

s1: abc, s2: abc
s1 and s2 is point to same memory: true
After s1 += "de";
s1: abcde, s2: abc
s1 and s2 is point to same memory: false

  -示意圖
    <程式碼5~9行>實體化字串"abc",將位址丟給s1,再把s1的位址丟給s2。所以現在s1等於s2,所指向的內容皆是"abc"。

String_Test_01_Illustrate
    <程式碼第10行>'+'在這裡表示字串的串接,但為了符合"Java字串永遠不變"這個規則,編譯器會先建立出一個新空間放字串"abcde",再讓s1指向他。
String_Test_01_Illustrate02
    <程式碼10~15行>所以現在的位址1和位址2不一樣了。

  - 動動腦
    Question:當程式中的第10行改成下面這樣時,會發生什麼是?

System.out.println("s1_1 and s1_2 is point to same memory: " + s1 == s2);

    Answer:
    <執行該行時>因為該行沒有優先權的問題(*/會先做),因此程式由左至右執行。當碰到'+'時將字串串接,並創造出一個新空間放它,再碰到"==",執行"該字串的位址和s2
的位址是否相等?"的比較,想當然永遠不等。
    另外創造的字串空間因為沒有人指向它,之後也會被Java資源回收機制回收記憶體。

String_Test_01_Illustrate03

  2. 另外String的宣告方式,在實際執行上也有差別:

  - 舉例來說:

/*------------------------------------------------------------
    這個程式是要測試,String的宣告方式和它對應的機制。
------------------------------------------------------------*/

public class String_Test02{
    public static void main(String[] args){
        String s1_1 = new String("abc");
        String s1_2 = new String("abc");
        System.out.println("s1_1 and s1_2 is point to same memory: " + (s1_1 == s1_2));

        String s2_1 = new String("def");
        String s2_2 = "def";
        System.out.println("s2_1 and s2_2 is point to same memory: " + (s2_1 == s2_2));

        String s3_2 = "ghi";
        String s3_1 = new String("ghi");
        System.out.println("s3_1 and s3_2 is point to same memory: " + (s3_1 == s3_2));

        String s4_1 = "jkl";
        String s4_2 = "jkl";
        System.out.println("s4_1 and s4_2 is point to same memory: " + (s4_1 == s4_2));
    }
}

  - 輸出結果:

s1_1 and s1_2 is point to same memory: false
s2_1 and s2_2 is point to same memory: false
s3_1 and s3_2 is point to same memory: false
s4_1 and s4_2 is point to same memory: true

  - 示意圖:
    String Literal Pool是一個專門存放字串指標的目錄。
    <程式碼第19~21行>jki
//續

留言