在 JDK 6 `String(String original)` 構造器中發現判斷:
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) { // 為什麼會發生?
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off + size);
} else {
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
JDK 6 中 `String` 使用 char[] value + int offset + int count 表示字符串,substring 不複製數組,直接共享:
public String substring(int beginIndex, int endIndex) {
// ... 邊界檢查 ...
return new String(offset + beginIndex, endIndex - beginIndex, value);
}
// 包私有構造器,共享 value 數組
String(int offset, int count, char[] value) {
this.value = value;
this.offset = offset;
this.count = count;
}
String s1 = "hello world"; // value.length=11, offset=0, count=11
String s2 = s1.substring(6); // value=同一數組, offset=6, count=5 ("world")
String s3 = new String(s2); // 調用 String(String original)
// 在構造器中:
// originalValue.length = 11 (共享的原始數組長度)
// size = original.count = 5 (s2 的邏輯長度)
// 11 > 5 → 進入複製分支
// off = 6, copyOfRange(value, 6, 11) → 新數組 ['w','o','r','l','d']
| 情況 | 處理 | 原因 |
|---|---|---|
originalValue.length == size | 直接共享數組 | 原字符串無偏移、無截取,數組恰好滿,安全共享 |
originalValue.length > size | 複製相關片段到新數組 | 原數組被共享且有未使用部分(offset>0 或 count |