Java中所有参数传递都是值传递,但可通过可变包装类(如IntRef)、标准容器类(如AtomicInteger、StringBuilder)或泛型Ref类让方法修改对象状态,从而在调用方看到“类似引用传递”的效果;函数式接口如Consumer也可实现安全回调式修改。

Java中所有参数传递都是值传递,但可以通过包装类或容器类让方法内部修改对象状态,从而在调用方看到“类似引用传递”的效果。关键不是改变引用本身,而是让引用指向的对象状态可变。
使用自定义可变包装类
针对基本类型(如int、boolean),最直接的方式是定义一个带public字段或getter/setter的包装类:
- 字段设为public,便于直接赋值(简洁但牺牲封装性)
- 或提供setXxx()方法,兼顾可变性与封装原则
- 避免仅用final字段或只读设计,否则无法实现“修改后可见”
示例:
public class IntRef { public int value; }void increment(IntRef ref) { ref.value++; }
IntRef x = new IntRef(); x.value = 5;
increment(x); // x.value 变为6
利用标准可变容器类
JDK自带的某些类天然适合做容器,前提是它们的状态可被修改:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- AtomicInteger:线程安全,支持incrementAndGet()等操作,适合并发场景
- StringBuilder:内容可变,适用于字符串拼接或中间结果传递
- 数组(如int[]):长度固定但元素可改,单元素数组常用于临时包装
- List/Set/Map:适合传递集合内容,方法内add/remove会影响原集合
注意:String、Integer等不可变类不能直接用于此目的,因为它们的“修改”实际创建了新对象。
用泛型增强复用性
为避免为每种类型写一个包装类,可设计泛型容器:
public class Ref<T> { public T value; }void updateName(Ref<String> nameRef) { nameRef.value = "Alice"; }
Ref<String> name = new Ref<>();
updateName(name); // name.value 现在是"Alice"
若需约束行为,可配合接口(如Mutable)或添加校验逻辑,但多数场景保持简单即可。
结合函数式接口简化调用
当目标是让方法能“回调式”修改外部变量时,可传入Consumer或BiConsumer:
void configure(Consumer<StringBuilder> config) {StringBuilder sb = new StringBuilder("start");
config.accept(sb); // 调用方决定如何改sb
System.out.println(sb); // 输出修改后的内容
}
这种方式不暴露容器实例,更安全,也更符合函数式风格。

















