String 不可變:一旦創建,內容不可更改。所有「修改」操作實際返回新對象。
Java 傳值調用:基本類型傳值,引用類型傳引用的值(即地址副本)。方法內修改引用指向不影響外部原引用。
public class Example {
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
public static void main(String[] args) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.println(ex.str); // good
System.out.println(ex.ch); // gbc
}
public void change(String str, char[] ch) {
str = "test ok"; // 參數 str 指向新對象,外部 ex.str 不變
ch[0] = 'g'; // 參數 ch 指向同一數組,修改內容影響外部
}
}
ex.str → "good" (0x100);ex.ch → ['a','b','c'] (0x200)str (參數) → 0x100;ch (參數) → 0x200str = "test ok":參數 str → "test ok" (0x300),ex.str 仍指向 0x100ch[0] = 'g':修改 0x200 處數組內容為 ['g','b','c'],外部可見public void change(String str, char[] ch) {
str = str.toUpperCase(); // 返回新字符串 "GOOD",參數 str 指向新對象
ch = new char[]{ 'm', 'n' }; // 參數 ch 指向新數組,外部 ex.ch 不變
}
// 結果:ex.str="good", ex.ch=['a','b','c']
toUpperCase() 不修改原對象,返回新對象ch = new ... 只改變參數局部引用,斷開與外部數組的關聯public final class String {
private final char value[]; // final 數組引用
private int hash; // 緩存 hashCode
// 所有構造器最終複製字符數組
// 所有「修改」方法返回 new String(newValue)
}
String s = "abc":編譯期確定,進常量池,相同字面量共享對象String s = new String("abc"):運行期在堆創建新對象,不進常量池(除非調用 intern())String.intern():若常量池已有相同內容返回池中引用,否則放入池並返回== 比較引用,equals() 比較內容