Java值传递,会影响原值的原因

基本数据类型

对于基本数据类型(如 intdoubleboolean 等),值传递不会影响原值。因为传递的是变量值的副本,方法内对副本的修改不会反映到原始变量上。

public class PrimitivePassingExample {
    public static void main(String[] args) {
        int num = 10;
        System.out.println("Before method call: " + num);
        modifyPrimitive(num);
        System.out.println("After method call: " + num);
    }

    public static void modifyPrimitive(int value) {
        value = 20;
        System.out.println("Inside method: " + value);
    }
}

在上述代码中,modifyPrimitive 方法接收的是 num 的一个副本,在方法内部修改这个副本的值不会影响到 main 方法中的 num 变量。

引用数据类型

当传递的是引用类型(如数组、对象等)时,传递的是对象引用的副本,这个副本和原始引用指向同一个对象。因此,在方法内部通过这个引用副本对对象状态进行修改,会影响到原始对象。

1. 数组
public class ArrayPassingExample {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println("Before method call: " + java.util.Arrays.toString(arr));
        modifyArray(arr);
        System.out.println("After method call: " + java.util.Arrays.toString(arr));
    }

    public static void modifyArray(int[] array) {
        array[0] = 10;
        System.out.println("Inside method: " + java.util.Arrays.toString(array));
    }
}

在这个例子中,modifyArray 方法接收的是 arr 引用的副本,这个副本和 arr 指向同一个数组对象。在方法内部通过 array[0] = 10; 修改了数组的第一个元素,由于指向的是同一个数组,所以 main 方法中的 arr 数组也受到了影响。

2. 自定义对象
class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}

public class ObjectPassingExample {
    public static void main(String[] args) {
        Person person = new Person("Alice");
        System.out.println("Before method call: " + person.name);
        modifyPerson(person);
        System.out.println("After method call: " + person.name);
    }

    public static void modifyPerson(Person p) {
        p.name = "Bob";
        System.out.println("Inside method: " + p.name);
    }
}

这里 modifyPerson 方法接收的是 person 引用的副本,副本和 person 指向同一个 Person 对象。在方法内部修改了 p.name 的值,由于指向的是同一个对象,所以 main 方法中的 person 对象的 name 属性也被改变了。

不过需要注意的是,如果在方法内部让引用副本指向一个新的对象,这不会影响原始引用指向的对象。

class Student {
    String name;

    public Student(String name) {
        this.name = name;
    }
}

public class NewObjectReferenceExample {
    public static void main(String[] args) {
        Student student = new Student("Tom");
        System.out.println("Before method call: " + student.name);
        changeStudent(student);
        System.out.println("After method call: " + student.name);
    }

    public static void changeStudent(Student s) {
        s = new Student("Jerry");
        System.out.println("Inside method: " + s.name);
    }
}

在 changeStudent 方法中,虽然让引用副本 s 指向了一个新的 Student 对象,但这不会影响 main 方法中 student 引用指向的原始对象,所以 student 对象的 name 属性保持不变。

结语:

综上所述,当传递引用类型的参数时,在方法内部通过引用副本修改对象的状态会影响到原始对象,但如果让引用副本指向一个新对象则不会影响原始对象。

你可能感兴趣的:(Java,java,开发语言)