首页 > 编程笔记

Java值传递和引用传递(小白必读)

Java 中方法的参数称为形参,向其传递的变量或常量称为实参。

Java 中的所有参数都采用值传递,也就是说,传递的是值的副本。在实参向形参传递值之后,程序如果改变形参的值,不会影响实参的值,同样,改变实参的值也不会影响形参的值。因此,得到的是“实参的复印件,而不是原件”。

Java值传递

对于基本数据类型的参数,传递的是值的副本,副本的改变不会影响原件。

此外,向形参传递的实参的值的级别不可以高于形参的值的级别。例如,不可以向方法的 int 型参数传递一个 double 型值,但可以向 double 型参数传递一个 int 型值。

【实例】基本数据类型参数的值传递
public class Test {
    public static void main(String[] args) { 
        int a = 2, b = 3; 
 
        System.out.println("交换前变量:a=" + a + ", b=" + b); 
        swap(a, b); 
 
        // 注意:swap方法中的变量交换不会影响main方法中的变量a和b,因为Java是按值传递的 
        System.out.println("交换后变量:a=" + a + ", b=" + b); 
    } 
 
    public static void swap(int a, int b) { 
        int temp; 
        temp = a; 
        a = b; 
        b = temp;  
        System.out.println("swap()方法中a的值为:" + a + "; b的值为:" + b); 
    }
}
运行结果为:

交换前变量:a=2, b=3
swap()方法中a的值为:3; b的值为:2
交换后变量:a=2, b=3

运行结果表明,main() 方法中的实参 a 和 b,在调用 swap() 方法前后,其值没有任何变化,声明 swap() 方法时的形参 a 和 b,并不是 main() 方法中的实参 a 和 b。所以,当基本数据类型作为参数传递时,改变形参的值不影响实参。

Java引用传递

当参数是引用类型时,传递的也是值的副本,但是引用类型的值指的是数组、对象等的地址,即传递的是实参变量中存储的“引用”,而不是变量引用的实体。

因此,副本和原参数都指向同一个“地址”,改变“副本”指向地址的对象的值,意味着原参数指向对象的值也发生了变化,反之亦然。

引用传值过程中的内存模型如下图所示:


图 1 引用传值过程中的内存模型

【实例】引用类型参数的值传递。
// 定义一个油箱类 
class PetrolTank { 
    double petrolAmount; // 变量命名应使用驼峰命名法 
 
    PetrolTank(double amount) { 
        petrolAmount = amount; 
    } 
} 
 
class Car { 
    void run(PetrolTank tank) { 
        tank.petrolAmount -= 7.5; // 消耗7.5单位的油 
    } 
} 
 
public class Example3_10 { 
    public static void main(String[] args) { 
        // 创建一个油箱对象,为油量赋初值 
        PetrolTank myTank = new PetrolTank(50.0); 
 
        // 显示汽车行驶之前的油量 
        System.out.println("当前油箱的油量显示:" + myTank.petrolAmount); 
 
        // 创建一个汽车对象 
        Car myCar = new Car(); 
        System.out.println("汽车启动,开始消耗油量"); 
        myCar.run(myTank);
        // 显示行驶后汽车油箱的油量 
        System.out.println("行驶后汽车油箱的油量显示:" + myTank.petrolAmount); 
    } 
}
运行结果为:

当前油箱的油量显示:50.0
汽车启动,开始消耗油量
行驶后汽车油箱的油量显示:42.5

运行结果表明,当执行mycar.run(mytank);语句后,mytank 引用值传递给 Car 类的成员方法 run() 中的形参 tank,两个对象名具有相同的实体。

推荐阅读