Java 只有值傳遞(Pass by Value)。無論基本類型還是引用類型,傳遞的都是「值的副本」。
String a = "123";
void change(String a) {
a = "234"; // 修改局部引用指向新對象
}
// 調用後:外部 a 仍為 "123"
Person p = new Person("張三");
void change(Person p) {
p = new Person("李四"); // 修改局部引用
}
// 調用後:外部 p 仍指向 "張三"
String 和自定義對象行為完全一致:都是修改局部變量的引用副本,不影響外部原引用。
StringBuilder sb = new StringBuilder("123");
void modify(StringBuilder sb) {
sb.append("456"); // 通過引用副本修改同一對象
}
// 調用後:外部 sb 變為 "123456"
Person p = new Person("張三");
void modify(Person p) {
p.setName("李四"); // 修改對象內部字段
}
// 調用後:外部 p.name 變為 "李四"
這時外部可見變化,因為引用副本指向同一堆內存對象。
String 無任何修改內部狀態的方法,所有「修改」操作都返回新對象String s = "abc" 可能復用常量池對象| 語言 | 機制 | 效果 |
|---|---|---|
| Java | 值傳遞(引用副本) | 無法在方法內修改外部引用指向 |
C# ref | 真引用傳遞 | 可修改外部引用指向 |
C++ & | 引用/別名 | 可修改外部引用指向 |
方法調用基於棧幀,參數入棧時:
C# ref/C++ & 本質是編譯器語法糖,底層同樣傳遞地址,但編譯器生成代碼允許修改調用者棧幀中的變量。