java String

概覽

String 被聲明爲 final,所以它不可被繼承。(Integer 等包裝類也不能被繼承)數組

在 Java 8 中,String 內部使用 char 數組存儲數據。緩存

在 Java 9 以後,String 類的實現改用 byte 數組存儲字符串,同時使用 coder 來標識使用了哪一種編碼。安全

value 數組被聲明爲 final,這意味着 value 數組初始化以後就不能再引用其它數組。而且 String 內部沒有改變 value 數組的方法,所以能夠保證 String 不可變。網絡

不可變的好處

能夠緩存 hash 值

由於 String 的 hash 值常常被使用,例如 String 用作 HashMap 的 key。不可變的特性可使得 hash 值也不可變,所以只須要進行一次計算。ui

String Pool 的須要

若是一個 String 對象已經被建立過了,那麼就會從 String Pool 中取得引用。只有 String 是不可變的,纔可能使用 String Pool。編碼

安全性

String 常常做爲參數,String 不可變性能夠保證參數不可變。例如在做爲網絡鏈接參數的狀況下若是 String 是可變的,那麼在網絡鏈接過程當中,String 被改變,改變 String 對象的那一方覺得如今鏈接的是其它主機,而實際狀況卻不必定是。spa

線程安全

String 不可變性天生具有線程安全,能夠在多個線程中安全地使用。線程

String VS StringBuffer VS StringBuilder

可變性

  • String 不可變
  • StringBuffer 和 StringBuilder 可變

線程安全

  • String 不可變,所以是線程安全的
  • StringBuilder 不是線程安全的
  • StringBuffer 是線程安全的,內部使用 synchronized 進行同步

String Pool

字符串常量池(String Pool)保存着全部字符串字面量(literal strings),這些字面量在編譯時期就肯定。不只如此,還可使用 String 的 intern() 方法在運行過程當中將字符串添加到 String Pool 中。code

當一個字符串調用 intern() 方法時,若是 String Pool 中已經存在一個字符串和該字符串值相等(使用 equals() 方法進行肯定),那麼就會返回 String Pool 中字符串的引用;不然,就會在 String Pool 中添加一個新的字符串,並返回這個新字符串的引用。對象

下面示例中,s1 和 s2 採用 new String() 的方式新建了兩個不一樣字符串,而 s3 和 s4 是經過 s1.intern() 方法取得一個字符串引用。intern() 首先把 s1 引用的字符串放到 String Pool 中,而後返回這個字符串引用。所以 s3 和 s4 引用的是同一個字符串。

若是是採用 如下這種字面量的形式建立字符串,會自動地將字符串放入 String Pool 中。

在 Java 7 以前,String Pool 被放在運行時常量池中,它屬於永久代。而在 Java 7,String Pool 被移到堆中。這是由於永久代的空間有限,在大量使用字符串的場景下會致使 OutOfMemoryError 錯誤。

new String("xxx")

使用這種方式一共會建立兩個字符串對象(前提是 String Pool 中尚未 "xxx" 字符串對象)。

  • 執行語句String str="xxx";時。首先查看字符串池中是否存在字符串"xxx",若是存在則直接將「xxx」賦給str,若是不存在則先在  字 符串池中新建一個字符串"xxx",而後再將其賦給str.
  • new 建立字符串時,首先查看池中是否有相同的字符串,若是有則拷貝一份放到堆中,而後返回堆中的地址;若是池中沒有則在堆中建立一分,而後返回堆中的地址,
相關文章
相關標籤/搜索