天天看點

不可變(Immutable)字元串

JAVA平台提供了兩個類:String和StringBuffer,它們可以儲存和操作字元串,即包含多個字元的字元資料。這個String類提供了數值不可改變的字元串。而這個StringBuffer類提供的字元串進行修改。當你知道字元資料要改變的時候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動态構造字元資料。

但是String類是内容不可改變的字元串

.1.2 不可變(Immutable)字元串

在Java中使用字元串有一個非常重要的規則必須記得, 一個字元串對象一旦被配置,它的内容就是固定不可變的。例如下面這個聲明:

String str = "caterpillar";       

這個聲明會配置一個長度為11、内容為caterpillar的字元串對象,您無法改變這個字元串對象的内容。不要以為下面的語句就是改變一個字元串對象的内容:

String str = "Just";       
str = "Justin";       

事實上在這個程式片段中會有兩個字元串對象,一個是Just字元串對象,長度為4;一個是Justin字元串對象,長度為6,兩個是不同的字元串對象。您并不是在Just字元串後加上in字元串,而是讓str名稱引用自Justin字元串對象。圖6-2展示出了這個概念。

不可變(Immutable)字元串

圖6-2  使用=作字元串指定的意義 在Java中,使用“=”将一個字元串對象指定給一個變量名稱,其意義為改變該名稱所引用的對象,原來被引用的字元串對象若沒有其他名稱來引用它,就會在适當的時候被Java的“垃圾回收”(Garbage Collection)機制回收。在Java中,程式設計人員通常不用關心無用對象的資源釋放問題,Java會檢查對象是否不再被引用,沒有被任何名稱引用的對象将會被回收。 在 Java 執行時會維護一個 String 池 (Pool) 。對于一些可以共享的字元串對象,會先在 String 池中查找是否存在相同的 String 内容 ( 字元相同 ) ,如果有就直接傳回,而不是直接創造一個新的 String 對象,以減少記憶體的耗用。如果在程式中使用下面的方式來聲明,則實際上是指向同一個字元串對象:

String str1 = "flyweight";      
String str2 = "flyweight";       
System.out.println(str1 == str2);      

當直接在程式中使用 "" 來包括一個字元串時,該字元串就會在 String 池中,上面的程式片段中的 flyweight 就是這樣的情況。 flyweight 在程式中會有一個執行個體,而 str1 與 str2 同時引用自 flyweight 。圖 6-3 表示了這個概念。

不可變(Immutable)字元串

圖6-3  字元串變量str1、str2同時引用自flyweight 在 Java 中如果 == 被使用于兩個對象類型的變量,它是用于比較兩個變量是否引用自同一對象,是以在圖6-3中當str1==str2比較時,程式的執行結果會顯示true。 再來看看關于String的intern()方法,先看一下API說明的節選(翻譯): 在intern()方法被調用時,如果池(Pool)中已經包括了相同的String對象(相同與否由equals()方法決定),那麼會從池中傳回該字元串,否則原String對象會被加入池中,并傳回這個String對象的引用。 這段話其實說明了Flyweight模式(參見本章的網絡索引) 的運作方式,直接使用範例6.4來說明會更清楚。 Ü 範例6.4  InternString.java                                                      public class InternString {     public static void main(String[] args) {         String str1 = "fly";         String str2 = "weight";         String str3 = "flyweight";         String str4 = null;           str4 = str1 + str2;         System.out.println(str3 == str4);           str4 = (str1 + str2).intern();         System.out.println(str3 == str4);     } }   style='使用圖形來說明這個範例,在聲明str1、str2、str3後,String池中的狀況如圖6-4所示。  

不可變(Immutable)字元串
不可變(Immutable)字元串

圖6-4  字元串池示意 在Java中,使用+串聯字元串會産生一個新的字元串對象,是以在程式中第一次比較str3與str4對象是否為同一對象時,結果會是false,如圖6-5所示。

不可變(Immutable)字元串

圖6-5  字元串加法會産生新的字元串 intern()方法會先檢查String池中是否存在字元部分相同的字元串對象,如果有就傳回。由于程式中之前已經聲明flyweight字元串對象,intern()在String池中發現了它,是以直接傳回。這時再進行比較,str3與str4所指向的其實會是同一對象,是以結果會是true,如圖6-6所示。

不可變(Immutable)字元串

圖6-6  intern()會傳回String池中字元串對象的引用 由以上的說明也得出一個結論,==在Java中被用來比較兩個變量名稱是否 引用自同一對象,是以不可以用 == 來比較兩個字元串的字元内容是否相同 。例如:

String str1 = new String("caterpillar");      
String str2 = new String("caterpillar");      
System.out.println(str1 == str2);      

雖然兩個字元串對象的字元值完全相同,但實際上在這個程式片段中,産生了兩個 String 的執行個體, str1 與 str2 分别引用自不同的執行個體。是以使用 == 比較時結果會顯示 false 。如果要比較兩個字元串對象的字元值是否相同,要使用 equals() 方法 ,以下的寫法才會顯示 true 的結果:

String str1 = new String("caterpillar");      
String str2 = new String("caterpillar");      
System.out.println(str1.equals(str2));      

 http://book.csdn.net/bookfiles/135/1001354627.shtml