Java值传递,会影响原值的原因
基本数据类型
对于基本数据类型(如 int
、double
、boolean
等),值传递不会影响原值。因为传递的是变量值的副本,方法内对副本的修改不会反映到原始变量上。
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
属性保持不变。
结语:
综上所述,当传递引用类型的参数时,在方法内部通过引用副本修改对象的状态会影响到原始对象,但如果让引用副本指向一个新对象则不会影响原始对象。