可以說字串操作是計算機程式設計中最為常見的行為
不可變的String
根據JDK檔案的說法,String類代表字串,Java程式中的所有字串文字(例如"abc")都被實作為此類實體,例如:
String string = "abc";
//相當于:
char[] data = {'a','b','c'};
String str = new String(data);
那為什么說String類是不可變的,看一段String類中的部分源代碼
哦~,原來是這樣,String類是被final修飾的,所以無法繼承該類,并且,其所有的成員變數都是私有(private)的,而且沒有提供修改私有變數的共有(public)方法,再者,關于對String物件的操作都沒有修改當前物件,而是新建一個物件
例如下面這個substing方法,如果回傳值不等于自身,該方法就會創建一個String物件,該物件為截取后的結果,而不是在原String物件上進行的

可能有些人就來疑問了,誰說的不能修改,看我這個,s1都被我改的毀容了
其實,這只是表面的錯覺而已
起初,3個參考(s1、s2、s3)分別指向各自的物件,如圖
執行第12行賦值陳述句后,并不是修改了s1所指的String物件(歐文),而是修改了參考s1,使其指向參考s2所指的String物件(艾弗森),如圖
執行第15行陳述句時,臨時的StringBuilder物件會連接s2與s3所指的物件,并呼叫toString方法創建一個String物件賦值給參考s1,即參考s1會指向這個新創建的String物件,如圖
從執行的程序可以看出,String物件“歐文”、“艾弗森”、“NB”在全程程序中都沒有改變,改變的只是參考s1所指向的內容,也就是s1的值,
下面的程式給予說明,String物件的不可變性,

可以看出,盡管對s1依次呼叫了3個方法(toUpperCase、concat和substring),但是s1指向的String內容始終沒有改變,而s2、s3與s4確實輸出了期望的結果,這是因為,String類提供的一系列操作字串內容的方法都不是在自身物件上進行的,而是新創建一個String物件,例如,當呼叫toUpperCase時,并不是修改s1自身指向的String物件,而是新創建了一個String物件,其內容就是s1內容的大寫形式,因此,這樣既可以滿足對String物件的各種操作要求,又保證了String物件的資料成員不會被外界修改,
那為什么要把String設計為不可變呢
其最大的好處就是可以實作資源共享,在對執行緒操作的時候,可以將其認為不可變的,而不用擔心其他執行緒會對其進行修改
要點總結
- String類是不可變類,其物件一旦創建,就不可修改,
- String類那些看似修改字符序列的方法實際上都是新創建的String物件,而不是修改自身物件
- 由于String物件是不可變的,因此其具有執行緒安全性,可以自由地實作共享