總是聽(tīng)大神說(shuō)String是不可變量,StringBuilder是線程不安全,StringBuffer是線程安全,嘚吧嘚一大堆記不住了。。。那有想過(guò)為什么嗎?今天來(lái)讀讀源碼解析一下。
StringBuilder
//定義一個(gè)StringBuilder對(duì)象
StringBuilder strBuilder=new StringBuilder("a");
//用兩個(gè)最常用的方法
strBuilder.append("b").toString();
解析,定義StringBuilder對(duì)象時(shí),進(jìn)入源碼時(shí)間
public StringBuilder(String str) {
//調(diào)用父類嘛 稍后給出關(guān)系圖
super(str.length() + 16);
append(str);
}
//父類構(gòu)造函數(shù)在這
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
//value聲明在這
char[] value;
由源碼可以看出,==定義一個(gè)StringBuilder對(duì)象即定義了一個(gè)char數(shù)組==
解析append()方法,進(jìn)入源碼時(shí)間
public StringBuilder append(String str) {
//又是調(diào)用父類方法
super.append(str);
return this;
}
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
//數(shù)組擴(kuò)容,擴(kuò)長(zhǎng)度*2+2
ensureCapacityInternal(count + len);
//字符復(fù)制到數(shù)組中
//該方法的作用是將當(dāng)前字符串從start到end-1位置上的字符復(fù)制到字符數(shù)組c中,并從c的offset處開(kāi)始存放
str.getChars(0, len, value, count);
//count為數(shù)組實(shí)際長(zhǎng)度
count += len;
return this;
}
最后一個(gè)toString方法,綜上很明顯,StringBuilder.toString()就是將數(shù)組轉(zhuǎn)成String,我們看看源碼
public String toString() {
return new String(value, 0, count);
}
的確是將數(shù)組轉(zhuǎn)成String輸出就好了,但是這個(gè)String構(gòu)造方法沒(méi)看懂啊。。。
接下來(lái)我們看看String,對(duì)了,StringBuffer沒(méi)看呢。來(lái),我們先看一下StringBuffer
構(gòu)造函數(shù)StringBuilder完全一致
關(guān)鍵append()方法
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
public synchronized String toString() {
return new String(value, 0, count);
}
對(duì)咯,關(guān)鍵就多了一個(gè)==synchronized==,所以實(shí)現(xiàn)線程同步。
String
此時(shí)涉及到一個(gè)常量池的概念
String.intern();將數(shù)據(jù)加入常量池
Integer int_1 = 40;
Integer int_2 = Integer.valueOf(40);
Integer int_3 = new Integer(40);
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}