面向对象学习笔记8 - Java的值传递机制
一、核心结论
Java中不存在引用传递,只有值传递。当传递基本数据类型时传递的是数据值本身,传递引用类型时传递的是对象地址值的副本。理解这个机制是避免开发中隐蔽Bug的关键。
二、案例解析
1. 局部变量赋值场景
class Order {
int orderId;
}
public class ValueTransferTest {
public static void main(String[] args) { // 修正数组声明语法
// 场景1:基本数据类型
int m = 10;
int n = m; // 值拷贝
m++;
System.out.println("m = " + m + ",n = " + n); // m=11,n=10
// 场景2.1:数组(引用类型)
int[] arr1 = new int[]{1,2,3,4,5};
int[] arr2 = arr1; // 地址值拷贝
arr1[0] = 10;
System.out.println(arr2[0]); // 输出10(共享堆中对象)
// 场景2.2:对象类型
Order order1 = new Order();
order1.orderId = 1001;
Order order2 = order1; // 地址值拷贝
order2.orderId = 1002;
System.out.println(order1.orderId); // 输出1002(共享对象)
}
}
2. 方法参数传递场景
class Person {
int age;
}
public class ValueTransferTest1 {
// 处理基本类型参数
public void method1(int m) {
m++; // 修改的是栈中的副本
}
// 处理引用类型参数
public void method2(Person p) {
p.age++; // 通过地址副本修改堆中对象
}
public static void main(String[] args) { // 修正数组声明语法
ValueTransferTest1 test = new ValueTransferTest1();
// 基本类型测试
int m = 10;
test.method1(m);
System.out.println("m = " + m); // 输出10(原值未变)
// 引用类型测试
Person p = new Person();
p.age = 10;
test.method2(p); // 修正缺少分号的问题
System.out.println(p.age); // 输出11(对象被修改)
}
}
三、本质总结
| 类型 | 传递内容 | 修改影响 |
|---|---|---|
| 基本数据类型 | 数据值副本 | 不影响原始数据 |
| 引用类型 | 地址值副本 | 修改对象属性会影响原对象 |
关键理解:无论传递的是基本类型还是引用类型,本质上都是值传递。引用类型之所以表现出"传递引用"的假象,是因为我们通过地址副本操作的是堆中的同一个对象实体。
四、常见误区
• 误区1:认为引用类型参数传递的是对象本身
• 正解:传递的是地址值的副本,如同复制一张钥匙的模具
• 误区2:在方法中重新new对象会影响原引用
public void method3(Person p){
p = new Person(); // 不会影响调用方的引用
p.age = 20;
}
此时修改的是方法栈中的地址副本,不会影响调用方的对象引用。
总结:取决于赋值赋的是值还是地址值,若为地址值,指向的是同一个实体,则改一个,另一个也会改,本质上取决于存的是什么。
掌握值传递机制,就能准确预判代码行为,写出更健壮的程序!

浙公网安备 33010602011771号