引用传递
详情
引用传递
- 当我们传递一个对象(如数组等对象类型)作为参数时,传递的是引用的副本(内存地址的拷贝),而非引用本身。函数对对象进行修改会影响原始对象。
实验一:修改对象内容(成功)→ 证明“共享同一对象”
public class ReferencePassingArray {
public static void modifyArray(int[] arr) {
System.out.println("方法内部修改前:arr[0] = " + arr[0]);
arr[0] = 100; // 修改的是引用指向的数组对象的内容
System.out.println("方法内部修改后:arr[0] = " + arr[0]);
}
public static void main(String[] args) {
int[] originalArray = {1, 2, 3};
System.out.println("调用方法前:originalArray[0] = " + originalArray[0]);
modifyArray(originalArray); // 将 originalArray 的引用复制一份传递给 modifyArray 方法
System.out.println("调用方法后:originalArray[0] = " + originalArray[0]);
}
}输出结果:
调用方法前:originalArray[0] = 1
方法内部修改前:arr[0] = 1
方法内部修改后:arr[0] = 100
调用方法后:originalArray[0] = 100解释:
- 在
main方法中,originalArray引用指向一个包含{1, 2, 3}的数组对象。 - 当调用
modifyArray(originalArray)时,originalArray这个引用(内存地址)被复制一份传递给了modifyArray方法的参数arr。 - 现在,
arr和originalArray这两个引用都指向同一个数组对象。 - 在
modifyArray方法内部,通过arr[0] = 100;修改了引用所指向的数组对象的第一个元素。 - 由于
arr和originalArray指向的是同一个对象,所以当modifyArray方法结束后,main方法中originalArray指向的数组的第一个元素也被修改为100。
实验二:交换引用本身(失败)→ 证明“传的是副本,非引用”
public class SwapFailureDemo {
static class Person {
String name;
Person(String n) { name = n; }
}
public static void swap(Person a, Person b) {
System.out.println("【方法内】交换前: a=" + a.name + ", b=" + b.name);
Person temp = a;
a = b; // 仅修改局部变量 a 的指向(副本)
b = temp; // 仅修改局部变量 b 的指向(副本)
System.out.println("【方法内】交换后: a=" + a.name + ", b=" + b.name);
}
public static void main(String[] args) {
Person x = new Person("Alice"); // 假设堆地址 0x100
Person y = new Person("Bob"); // 假设堆地址 0x200
System.out.println("【主函数】调用前: x=" + x.name + ", y=" + y.name);
swap(x, y); // 传递 x(0x100) 和 y(0x200) 的副本
System.out.println("【主函数】调用后: x=" + x.name + ", y=" + y.name);
}
}【主函数】调用前: x=Alice, y=Bob
【方法内】交换前: a=Alice, b=Bob
【方法内】交换后: a=Bob, b=Alice // ⚠️ 仅方法内局部变量交换
【主函数】调用后: x=Alice, y=Bob // ❌ 外部引用完全未变!内存动态解析:
主函数栈帧:
x ──[纸条: 0x100]──→ [堆0x100: Alice]
y ──[纸条: 0x200]──→ [堆0x200: Bob]
调用 swap 时(复制纸条):
a ──[复印纸条: 0x100]──→ [堆0x100: Alice]
b ──[复印纸条: 0x200]──→ [堆0x200: Bob]
swap 内执行 a = b:
a ──[涂改后: 0x200]──→ [堆0x200: Bob] ← 仅改复印纸条!
b ──[涂改后: 0x100]──→ [堆0x100: Alice]
方法结束 → 复印纸条销毁
主函数纸条原封不动:
x ──[0x100]──→ Alice
y ──[0x200]──→ Bob关联网络
演化日志
- v0.1 (2025-05-18):初始版本
- v0.2 (2026-01-30):补充关联网络、演化日志、附件参考、待办事项