面向对象学习笔记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;
}

此时修改的是方法栈中的地址副本,不会影响调用方的对象引用。

总结:取决于赋值赋的是值还是地址值,若为地址值,指向的是同一个实体,则改一个,另一个也会改,本质上取决于存的是什么。

掌握值传递机制,就能准确预判代码行为,写出更健壮的程序!


posted @ 2025-03-13 16:04  谁来着?  阅读(26)  评论(0)    收藏  举报