字串

由於 Java 字串是不可變的 ,因此操作 String 的所有方法都將返回一個新的 String 物件。他們不會改變原來的 String。這包括 C 和 C++程式設計師期望改變目標 String 物件的子字串和替換方法。

如果要連線兩個以上在編譯時無法確定其值的 String 物件,請使用 StringBuilder 而不是 String。這種技術比建立新的 String 物件和連線它們更有效,因為 StringBuilder 是可變的。

StringBuffer 也可以用來連線 String 物件。但是,此類的效能較差,因為它設計為執行緒安全的,並在每次操作之前獲取互斥鎖。由於在連線字串時幾乎從不需要執行緒安全性,因此最好使用 StringBuilder

如果你可以將字串連線表達為單個表示式,那麼最好使用+運算子。Java 編譯器將使用 String.concat(...)StringBuilder 將包含+連線的表示式轉換為有效的操作序列。顯式使用 StringBuilder 的建議僅適用於串聯涉及多個表示式時。

不要將敏感資訊儲存在字串中。如果有人能夠獲取正在執行的應用程式的記憶體轉儲,那麼他們將能夠找到所有現有的 String 物件並讀取其內容。這包括無法訪問且正在等待垃圾收集的 String 物件。如果這是一個問題,你需要在完成後立即擦除敏感字串資料。你不能用 String 物件做到這一點,因為它們是不可變的。因此,建議使用 char[] 物件來儲存敏感字元資料,並在完成後擦除它們(例如,用'\000'字元覆蓋它們)。

所有 String 例項是在堆上建立的,甚至是與字串文字對應的例項。關於字串文字的特殊之處在於 JVM 確保所有相等的文字(即由相同字元組成)由單個 String 物件表示(此行為在 JLS 中指定)。這是由 JVM 類載入器實現的。當類載入器載入一個類時,它會掃描在類定義中使用的字串文字,每次看到它時,都會檢查字串池中是否已存在該文字的記錄(使用文字作為鍵)。如果已存在文字的條目,則使用對作為該文字對的儲存的 String 例項的引用。否則,將建立一個新的 String 例項,併為字串池中的文字(用作鍵)儲存對例項的引用。字串實習 )。

字串池儲存在 Java 堆中,並受到正常的垃圾回收。

Version < Java SE 7

在 Java 7 之前的 Java 版本中,字串池被儲存在稱為 PermGen 的堆的特殊部分中。這部分只是偶爾收集。

Version >= Java SE 7

在 Java 7 中,字串池已從 PermGen 中移除。

請注意,可以從使用它們的任何方法隱式地訪問字串文字。這意味著如果程式碼本身是垃圾收集的,那麼相應的 String 物件只能被垃圾收集。

直到 Java 8,String 物件被實現為 UTF-16 char 陣列(每個字元 2 個位元組)。在 Java 9 中有一個提議將 String 實現為帶有編碼標誌欄位的位元組陣列,以便注意字串是否被編碼為位元組(LATIN-1)或字元(UTF-16)。