Skip to content

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

660字约2分钟

2024-09-12

在 Java 中,参数传递始终是按值传递(Pass by Value),但理解这一点有时会让人困惑,因为它的表现取决于传递的参数类型。

基本数据类型的参数传递:

对于基本数据类型(int, float, boolean, char 等),Java 传递的是实际的值。因此,在方法中对参数进行修改不会影响到原来的变量。

示例:

public class Main {
    public static void main(String[] args) {
        int num = 10;
        modify(num);
        System.out.println(num);  // 输出 10,num 的值没有改变
    }

    public static void modify(int n) {
        n = 20;  // 修改的是副本,不会影响原来的 num
    }
}

在这个例子中,num 的值并不会因为在 modify() 方法中对参数 n 的修改而改变。因为传递的只是 num 的副本。

对象类型的参数传递:

对于对象类型(包括数组),Java 传递的是对象引用的副本,即传递的是对象引用的值,而不是对象的实际引用。因此,传递的引用本身是按值传递的,但通过这个引用可以修改对象的内部状态。

示例:

class Person {
    String name;
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.name = "Alice";
        modify(person);
        System.out.println(person.name);  // 输出 "Bob",person 的 name 被修改
    }

    public static void modify(Person p) {
        p.name = "Bob";  // 通过对象引用修改对象的属性
    }
}

在这个例子中,person 对象的引用被按值传递到 modify() 方法,但由于这个引用指向的还是同一个对象,方法内对 name 属性的修改会影响到原始对象。

注意:

尽管你可以修改对象的属性,你不能改变对象引用本身,因为传递的引用也是按值传递的。因此,方法内试图让引用指向一个新对象不会影响原始对象。

示例:

class Person {
    String name;
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.name = "Alice";
        modify(person);
        System.out.println(person.name);  // 仍然输出 "Alice"
    }

    public static void modify(Person p) {
        p = new Person();  // 试图修改引用本身,效果仅在方法内部
        p.name = "Bob";
    }
}

在这个例子中,虽然在 modify() 方法中 p 被赋值为一个新的对象,但这只是修改了局部变量 p,并不会影响 main() 方法中的 person 对象。

总结:

  • 对于基本数据类型,Java 按值传递实际的值。
  • 对于对象类型,Java 按值传递对象引用的副本,方法内部可以通过这个引用修改对象的属性,但不能改变引用本身指向的对象。