Java 中的参数传递是按值还是按引用?
在 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 按值传递对象引用的副本,方法内部可以通过这个引用修改对象的属性,但不能改变引用本身指向的对象。