古詩詞大全網 - 成語用法 - String 類

String 類

String 是不可變類,不可變的意思是 String 類型變量初始化後,其引用指向內存內容不能改變,變量引用可以指向其他內存。

定義壹個 String 變量 str,引用指向內存字符串 abc。

變量賦值時,新開辟內存 def 字符串,str 引用指向新對象,原內存內容 abc 不變。

String 類是壹個字符串數組的封裝類(內部壹個 char[] 數組)。數組類型 final private,引用 value 值不可變,外部無法訪問。

因此,String 對象本質是指向壹個 char 數組內存的引用,設計成 final 不可變類型,壹旦 String 對象創建,value 值初始化,指向壹塊字符數組內存,char[] 引用不可變,String 對象即不可改變。

替換字符串中的某個字符,String 類 replace() 方法,不直接更改 char[] 引用指向內存,而是開辟壹塊新內存。

創建新 char[] 數組,分配內存,長度和老數組壹致,復制,替換,new 壹個新 String 類對象,在構造方法,新 char[] 數組賦值 String 類內部 value,返回新 String 引用。

class 文件常量池,在文件中,編譯器編譯生成字面量和符號引用,未載入內存,字面量是文本字符串,(如 String str = "abc" 中的 abc)。

符號引用是類/接口全限定名,(如 java/lang/String ),變量名稱( str ),方法名稱和描述符(參數和返回值)。

類加載內存後,class 文件常量池(字面量和符號引用),進入方法區運行時常量池,該常量池區全局***享。

字面量(字符串常量池), jdk1.7 後不再方法區,移到堆中,符號引用如方法名、類全限定名仍然在方法區。

定義壹個 String 變量 a,編譯後 hello2 是文本字符串,在 class 文件常量池,編譯階段確定 a 的值。

兩個字符串字面值,編譯時會進行優化(拼接),解析成壹個,所以 a2 在編譯期由編譯器直接解析為 hello2。

反編譯 javap -verbose StrClass.class 命令,查看 class 文件常量池。

編譯時會檢查常量池是否已存在 hello2 字符串,只有壹個 #2,String,對應 #22,即 hello2。

此過程會查找字符串常量池是否存在 hello2,若不存在,在堆創建 char[] 數組,創建 String 對象關聯 char[] 數組,保存到字符串常量池,最後將a指向這個對象。

編譯階段,不能確定 a3 的值,定義 final 變量 c,字節碼替換掉 a4 中的 c 變量,場景和 a2 壹致。

(運行時)對象變量初始化,new 壹個 StringBuilder 對象,a3 引用指向 toString() 方法在堆內存 new 的 String 對象。a==a4,指向字符串常量池,a3 指向堆內存 new 的 String 對象。

類加載時,在常量池創建對象 hello2,變量 a5,運行時堆內存 new壹個 String 對象,字符串 hello2 已經在常量池,#2項,a 引用指向字符串常量池,a5 引用指向堆內存新對象,(a!=a5)。

class 文件常量池,hello2 文本字符。

類加載內存時,在字符串常量池創建壹個 hello2 字符串對象。

對象初始化時,new 指令,在堆中再次創建壹個對象,變量 a6 引用指向它。

class 文件常量池只有 hello 和 2 字符串,沒有 hello2 字符串,當類加載時,在字符串常量池不存在 hello2 對象。

初始化時,new 指令在堆創建兩個 String 對象( hello和2 ),通過 StringBuffer 類 append() 方法,toString() 方法在堆內存中 new 壹個 String 對象 (hello2),a7 引用指向它。

前壹節的變量 a3=b+2 賦值時,class 字節碼中定義了壹個 StringBuilder 類,調用兩次 append() 方法,依次添加 b 和 2 ,即 hello 和 2,壹次 toString() 方法,堆內存創建對象。

StringBuffer 和 StringBuilder 區別是線程安全。

StringBuffer 通過 char[] 數組保存數據,每壹個 append() 方法的新增數據在 char[] 數組保存,支持不同類型,boolean 類型保存4或5個字符 (true/false),字符串將每個字符保存,StringBuffer 類可以對字符串進行修改,進行字符串拼接時,不會產生新對象,直接對 char[] 數組進行操作更改。

幾乎所有的字符操作方法都 synchronized 同步,該類線程安全。

toString() 方法,創建壹個 String 對象,關聯 char[] 數組。

任重而道遠