Java中StringBuilder传参传递的是引用值,方法内修改内容会影响原对象,但重赋值引用不影响调用方;String不可变,所有操作均生成新对象。

Java中将StringBuilder作为方法参数传递时,实际传递的是对象的引用(即堆内存中该实例的地址),而非新拷贝。这意味着方法内部对StringBuilder内容的修改(如append()、delete()、setCharAt()等)会直接影响原始对象,但若在方法内重新赋值引用(如sb = new StringBuilder()),则不会影响调用方持有的原引用。
传递的是引用,不是副本
StringBuilder是可变对象,其变量本身存储在栈上,而实际字符数组和状态(如count)位于堆中。传参时,栈上的引用值被复制并传入方法——两个引用指向同一块堆内存。因此:
- 调用
sb.append("x")会改变原对象的value[]数组和count - 调用
sb.setLength(0)或sb.delete(0, sb.length())也会清空原始内容 - 这与
String不同——String不可变,所有“修改”操作都返回新对象
重新赋值引用不影响外部
如果在方法内部让形参指向新对象,仅改变当前栈帧中的引用值,调用方的引用仍指向原对象:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
void modifyRef(StringBuilder sb) {
sb = new StringBuilder("new"); // ← 仅修改本地引用
sb.append(" object");
}
StringBuilder original = new StringBuilder("old");
modifyRef(original);
System.out.println(original); // 输出 "old",未变
常见误用与建议
容易混淆的点在于:以为“传引用”就等于“可以任意替换原对象”,其实Java始终是“按值传递”,只是这个“值”是引用类型地址。实践中建议:
立即学习“Java免费学习笔记(深入)”;
- 若需避免副作用,应在调用前显式克隆:
new StringBuilder(original) - 若方法职责是修改传入的
StringBuilder,应明确命名(如appendTo(sb, text))并在文档中说明 - 不依赖方法内重赋值来“返回”新对象;需要新实例时,应通过返回值传递
对比 StringBuffer 和 String
StringBuffer行为与StringBuilder一致(同为可变引用类型),区别仅在线程安全性;而String作为不可变类,任何操作均生成新对象,原引用不受影响。例如:
void tryModifyString(String s) {
s += " world"; // 创建新String,s指向它
}
String str = "hello";
tryModifyString(str);
System.out.println(str); // 仍是 "hello"

















