Java 中的参数传递是按值还是按引用?

2024-08-25 08:57:12 176
Java 中的参数传递是 **按值传递** (Pass by Value),这意味着在方法调用时,传递给方法的是参数值的副本,而不是参数本身。

具体解释

  • 基本数据类型(如 int, double 等): 当你传递一个基本数据类型的参数时,传递的是这个值的副本。因此,在方法内部对参数的修改不会影响到原来的值。

  • 引用类型(如 对象, 数组 等): 当你传递一个对象或数组时,传递的实际上是引用的副本(即指向对象的地址)。因此,在方法内部通过引用修改对象的属性会影响到原来的对象,但如果你在方法内部修改了引用本身(让它指向一个新的对象),则不会影响原来的对象。

示例讲解

基本数据类型 - 按值传递

public class Main {
    public static void main(String[] args) {
        int num = 10;
        modifyValue(num);
        System.out.println("After method call, num: " + num); // 输出:After method call, num: 10
    }

    static void modifyValue(int n) {
        n = 20; // 修改的是 n 的副本
    }
}

在这个例子中,num 传递给 modifyValue 方法时,nnum 的副本,修改 n 不会影响原来的 num

引用类型 - 按值传递引用的副本

class Dog {
    String name;
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.name = "Buddy";

        modifyDogName(myDog);
        System.out.println("After method call, dog's name: " + myDog.name); // 输出:After method call, dog's name: Max
    }

    static void modifyDogName(Dog dog) {
        dog.name = "Max"; // 修改了 dog 引用指向的对象的属性
    }
}

在这个例子中,myDog 传递给 modifyDogName 方法时,dogmyDog 引用的副本。通过这个副本修改对象的属性(即 name),会影响到原来的对象。

引用重新赋值 - 不影响原始引用

class Dog {
    String name;
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.name = "Buddy";

        reassignDog(myDog);
        System.out.println("After method call, dog's name: " + myDog.name); // 输出:After method call, dog's name: Buddy
    }

    static void reassignDog(Dog dog) {
        dog = new Dog(); // 重新分配 dog 引用,不影响原始引用
        dog.name = "Max";
    }
}

在这个例子中,方法内部 dog 引用了一个新的对象,但这不会影响到 myDog,因为它们是不同的引用。myDog 仍然指向原来的对象,因此 name 仍然是 "Buddy"

总结

Java 中参数传递始终是按值传递。当你传递基本数据类型时,传递的是值的副本;当你传递引用类型时,传递的是引用的副本。这意味着你可以通过引用修改对象的状态,但不能改变原始引用本身。