Java 值传递和引用传递区别
在学习Java编程时,很多新手都会在“参数传递”上踩坑,比如明明给方法改了值,返回后变量却没变化,这往往是没搞懂传递方式的问题。很多人会混淆“值传递”和“引用传递”,其实用生活化的例子就能轻松区分,完全不用记晦涩的定义。
什么是值传递?就像复印钥匙
你可以把值传递理解成“复印钥匙开门”。假设你家里有一把房门钥匙(这就是要传递的“值”),你复印了一份给朋友,朋友拿着复印件去开门,能打开门,但复印件本身只是原来钥匙的复制版,和你手里的真钥匙是两个独立的东西。

在Java里,值传递就是方法接收的是传入值的副本,不是原变量本身。比如你写了一个方法,想把传入的数字加10,方法里改的是副本,原变量不会变:
`java
public class Test {
// 方法接收的是int的副本
public static void addTen(int num) {
num = num + 10;
}
public static void main(String[] args) {
int a = 5;
addTen(a);
System.out.println(a); // 输出还是5,不是15
}
}
`
这里的a就像真钥匙,方法里的num是复印的副本,改副本不影响真钥匙,这就是值传递的特点。
什么是引用传递?就像给朋友指路去你家
再说说引用传递,很多人会把这个和值传递搞混,其实它是“给朋友指路,让朋友去你家”。这里的“引用”不是你家房子本身,而是你家的地址——朋友拿到地址后,能找到你家,甚至可以在你家调整家具,但如果朋友改了地址(比如改成另一个小区),不会影响你原来的地址。
不过要注意,Java里没有真正的引用传递,很多人以为的“引用传递”,其实是“传递引用的副本”,相当于“给朋友复印了你的住址条”,朋友拿着复印件找你家,改复印件的地址,不会影响你手里的原住址条。用Java的对象来举例就很清楚:
`java
class Person {
String name;
Person(String name) { this.name = name; }
}
public class Test {
// 方法接收的是Person引用的副本
public static void rename(Person p) {
p.name = "小明"; // 改的是原对象的属性
p = new Person("小红"); // 改的是引用副本的指向,不影响原变量
}
public static void main(String[] args) {
Person myFriend = new Person("小刚");
rename(myFriend);
System.out.println(myFriend.name); // 输出小明,不是小红
}
}
`
这里myFriend是原引用,指向“小刚”的对象;方法里的p是引用的副本,一开始也指向同一个对象,所以改p.name会同步改原对象的属性,但p = new Person("小红")是让副本指向新对象,原引用myFriend的指向没变,所以输出还是“小明”。
一句话总结:Java里只有值传递
很多新手会纠结“什么时候用引用传递”,其实记住:Java的参数传递只有值传递这一种方式。对于基本类型(比如int、char),传递的是值的副本;对于引用类型(比如对象、数组),传递的是引用地址的副本,不是对象本身,也不是地址本身。
这样一来,不管是改基本类型没变化,还是改对象属性会变化,改对象的指向没变化,就都能说通了。搞懂这个,写代码时就不会再因为参数传递的问题出现莫名其妙的bug啦。