一、String的解析 1.String的含義 ①String是不可以被繼承的,String類是final類,String類是由char[]數組來存儲字元串。 ②String是不可變的字元序列,如果存儲abc則在字元串常量池中開闢長度固定為3的字元數組,無論怎麼改變均會產生新的實例。 2.Strin ...
一、String的解析
1.String的含義
①String是不可以被繼承的,String類是final類,String類是由char[]數組來存儲字元串。
②String是不可變的字元序列,如果存儲abc則在字元串常量池中開闢長度固定為3的字元數組,無論怎麼改變均會產生新的實例。
2.String的方法
由上圖可知String的方法,不是在原有字元串的基礎上進行修改的,都是new出了新的實例,因為String是不可變的字元序列。Sring對象的任何改變都不會改變原有的字元串。
二、字元串常量池的概念
1.String c = “abc” String cc = new String(“abc”)在記憶體中分佈情況?
①Sting c = “abc” 先在字元串常量池中查找,如果常量池中沒有,就實例化該字元串,並放到常量池中;如果池中存在abc,直接將字元串的地址賦值給c,c指向常量池的abc。
②String cc = new String(“abc”) 先在字元串常量池中找abc,如果存在再在堆中開闢一個空間指向常量池中的abc,棧中的cc指向堆中的0x12.
③一共開闢了4塊記憶體空間,String cc = new String(“abc”)如果池子中有abc則,創建一個對象,如果池子中沒有abc則創建2個對象。
④String cc = new String (“dec”) 的執行順序是先從右向左。先判斷dec在常量池中是否存在。如果不存在實例化一個放入池子中,再new堆中的對象。
2.分情況說明
①非new實例,結果是true,都是指向的字元串常量池中123。
②new實例,結果是false一個指向池子,一個指向堆記憶體,地址不一致。
③new實例2,結果是false,只要是new 出的實例在記憶體中就會開闢空間,二者的地址不一致,所以返回false。
④一個字元串由多個字元串拼接而成時,它本身也是字元串常量。
new出的對象不能再編譯期間確定,cz02和cz03也不能再編譯器確定。cz04和cz05都指向堆記憶體,cz04的值是在程式運行時確定的。
【常量找池,變數找堆】
⑤編譯期優化,jvm將+連接優化為連接後的值,在編譯期其值就是”a1”.
⑥字元串常量拼接和字元串引用的拼接,常量的”+”拼接是在編譯期完成的,而字元串引用拼接(“+”),是在程式運行時確定的。一個在指向字元串常量池,一個指向堆記憶體。
三、String、StringBuilder、StringBuffer解析和比較
1.String簡單總結
①String不可變的字元序列
②new的對象,一定是創建了對象,在堆中開闢空間。
③直接賦值和new兩種方式創建String類型的對象。
④直接賦值不一定創建對象,如果字元串常量池中有的話就直接堆中的實例指向常量池中,不需要創建對象。
⑤final修飾類,不能被繼承。
⑥String a = “1”+“2”+“3”+“4”;這個字元串拼接過程要產生多個對象完成,效率比較低。
2.String和StringBuilder、StringBuffer的區別?
①可變性:String不可變的字元序列,Builder和Buffer是可變的字元序列。
②線程安全:String是線程安全的,StringBuilder是線程不安全的,StringBuffer是線程安全。StringBuidler效率高於StringBuffer。因為String是不可變的一般情況下,效率最低。
③使用方式:如果字元串變換較少,使用String類型,如果拼接操作較多使用StringBuilder,如果要求線程安全使用StringBuffer。
3.StringBuffer可變字元序列的解析
①初始容量為16
②自動擴容:初始容量的2倍加2