java参数传递本质是值传递,克隆与否决定传入对象是否与原对象共享引用:直接传参共用同一实例,修改相互影响;浅拷贝仅复制对象本身,引用字段仍共享;深拷贝则完全隔离。

Java中对象克隆(Cloneable)与直接传参,本质区别不在“是否克隆”,而在于**你拿到的是谁、改它会不会影响原对象**。方法参数传递本身永远是值传递,克隆只是帮你提前造出一个“不共享引用”的新对象,避免后续修改互相干扰。
参数传递的本质:永远是值传递
Java里没有引用传递。无论是传基本类型还是对象,实际传入方法的都是一个“副本”:
- 基本类型:传数值副本,方法内改它,原变量不受影响;
- 引用类型:传的是“对象地址的副本”——也就是指向堆中同一块内存的另一个指针。只要没重新赋值(比如
obj = new Xxx()),对这个副本调用setXxx(),就是在操作原对象。
直接传参(不克隆):共用同一份数据
这是最常见也最容易踩坑的方式:
void process(Person p) { p.setName("改了"); }- 调用
process(p1)后,p1.getName()就变成“改了”; - 因为
p和p1指向同一个Person实例,改的是堆里的那一个对象。
先克隆再传参:获得独立副本
克隆不是传参方式的替代,而是**在传参前主动创建隔离对象**:
- 浅拷贝:
Person p3 = p1.clone(); process(p3);→ 如果Person只含基本类型或不可变字段(如String),通常够用; - 深拷贝:
Person p4 = p1.deepClone(); process(p4);→ 当Person包含可变引用字段(如Address address),必须确保address也被复制一份,否则p4.getAddress().setCity("北京")仍会改到p1的地址。
关键对比:改完之后谁变了?
假设原始对象 p1 有 name="张三"、address=new Address("上海"):
- 直接传参
process(p1)并执行p.setName("李四")→p1.name变成“李四”; - 浅拷贝后传参,且
address是引用类型 →p1.address和拷贝对象的address仍是同一个实例,改它的城市会影响p1; - 深拷贝后传参 →
p1完全不受影响,名字、地址、地址里的字段都各自独立。
克隆解决的不是“怎么传”,而是“传什么”。传参机制本身不会变,但你传进去的那个对象,是不是和原对象真正解耦,取决于你有没有做对的拷贝。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











