String底層詳解

String的底層實現原理

public final class String implements java。io。Serializable, Comparable, CharSequence { /** The value is used for character storage。 */ private final char value[];複製程式碼

可以看到 String 是被final所修飾的,這意味著String不可被繼承同樣可以看到String的底層其實是一個char型的陣列,同樣被final修飾,變成了常量。這裡提一嘴fianl ,final可以修飾類,方法,變數 被fianl修飾的類不可被繼承,被final修飾的方法不可被過載,被fianl修飾的變數會變成常量,一經初始不可更改複製程式碼

String的賦值

String的運用有兩種,一種是“=” 號直接賦值,另一種是new String(“xxx”)賦值 這兩種是有區別的,首先說“=”號賦值的這種複製程式碼

String str = “abc”;複製程式碼

“=” 號的賦值方式並不會在堆上建立新的物件,而是在常量池中搜索如果常量池中有這個字元則直接引用這個字元的地址如果沒有這個字元,則會在常量池中建立該字元,並引用地址字元常量池中不存在兩個相同的字元,也就是說 複製程式碼

String str1 = “abc”;String str1 = “abc”;System。out。println(str1==str2);//true//二者引用的地址是相同的,都指向一個字元複製程式碼

String str2=new String(“abc”);複製程式碼

new String() 意味著建立了一個新的物件,就意味著會在堆上分配一塊記憶體但並不是說這個字元就儲存在了堆上,而是儲存了一個地址,這個地址仍然指向字元常量池有人說字元已經初始就不可更改了,那我要是像更改有什麼辦法嘛複製程式碼

String str=“abc”; System。out。println(str); System。out。println(str+“456”); System。out。println(System。identityHashCode(str)); System。out。println(System。identityHashCode(str+“456”));輸出結果:abcabc45615289025771927950199複製程式碼

可以看出雖然用“+”號似乎可以增加新的字元,但是缺並不是原先的物件了,二者記憶體地址不同而且也只能進行字元新增,要想修改字元的內容,就要看下面兩個類了複製程式碼

StringBuffer和StringBuilder

這是我找到的一張關係圖,可以看出 StringBuffer和StringBuilder都是繼承自AbstractStringBuilder

String底層詳解

要想改變字元,StringBuffer和StringBuilder都為我們提供了一些方法增加字元:append 方法刪除字元:delete 方法反轉字元:revers 方法替換字元: replace 方法還有一些其他方法就留著下回探索複製程式碼

既然兩個類都可以對字元進行修改,哪兩者到底有什麼區別呢?

StringBuffer是執行緒安全的,StringBuilder是非執行緒安全的其實就是StringBuffer在一些方法加上了synchronized關鍵字加鎖了這樣他就可以支援併發操作 在不考慮併發的情況下,StringBuilder的效率是要高於StringBuffer的 因為不需要加鎖和釋放鎖複製程式碼

擴容機制:

public final class StringBuffer extends AbstractStringBuilder implements java。io。Serializable, CharSequence{ private transient char[] toStringCache; static final long serialVersionUID = 3388685877147921107L; public StringBuffer() { super(16); }複製程式碼

可以看見,StringBuffer陣列的初始長度是16(StringBuilder也是),當長度不夠的時候,會觸發擴容機制,會建立一個新的陣列,長度是原陣列的二倍+2,再把原陣列的元素複製過去複製程式碼

private int newCapacity(int minCapacity) { // overflow-conscious code 擴大2倍+2 //這裡可能會溢位,溢位後是負數哈,注意 int newCapacity = (value。length << 1) + 2; if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } //MAX_ARRAY_SIZE的值是Integer。MAX_VALUE - 8,先判斷一下預期容量(newCapacity)是否在0

作者:冷漠的麻辣燙

連結:https://juejin。cn/post/7018392166837780493

著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。