public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
由源碼知道string是由final修飾的,并且其中的char數組value[](以字符數組的形式用來保存字符串)也是由final修飾的。但是我們知道數組是引用變量類型,當final修飾引用變量的時候,變量中保存的地址是不能更改的,但是指針指向的數組本身是可以更改的。如果分析到這里有錯的話請指出,沒錯的話接著看核心問題。
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
當我們調用concat方法試圖從一個字符串后面增添字符,根據這段源碼。它先是通過Array.copyOf()方法new出一個長度合適的新字符數組。
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
然后可以看到,調用了System類中的arraycopy()方法。
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
最后調用了這個native方法來進行數組拷貝,所以為什么要采用這樣一個思路來處理string的concat操作?(其實可以拓展到所有對string的改變操作,這也是我真正想弄懂的地方,只是用concat來描述問題比較方便。)特別是前面提到的,既然final修飾并不能限制數組本身的改變,為什么不對字符數組進行修改以達到字符串內容的修改?就算指針受final限制而不能更改,但這樣的方式一樣可以達到改動string的目的不是嗎?
2 回答

波斯汪
TA貢獻1811條經驗 獲得超4個贊
我真特么蠢,剛才瞄了一眼AbstractStringBuilder源碼就想通了,我提出的這個問題恰好迎合了StringBuffer或StringBuilder的目的。啥都被你String做完了,還要別人來干嘛?況且你String還有更多其它的用處呢。
以append方法為例。它就是采用的擴容數組、然后拷貝字符串數組、直接返回當前字符數組。從而達到不產生新對象的目的。
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
添加回答
舉報
0/150
提交
取消