字串
由於 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)。