Java 为什么只有值传递
一、参数传递给方法的方式
在程序设计语言中,参数传递给方法的方式有两种:
-
按值调用(call by value)表示方法接受的是调用者提供的值。
-
按引用调用(call by reference)表示方法接受的是调用者提供的变量地址。
一个方法可以修改传递引用所对应的变量值,但不能修改传递值调用所对应的变量值。
二、Java 总是按值调用
方法参数共有两种类型:
- 基本数据类型
- 对象引用
当方法参数为基本类型时,我们看一下是否可以改变变量值:
public static void raise(int x) {
x = 3 * x;
}
public static void main(String[] args) {
int x = 10;
raise(x);
System.out.println(x);
}
程序运行结果为 10。我们发现 x 并没有改变。我们看一下方法具体的执行过程:
(1)add 方法参数 x 获得 main 方法 x 的拷贝值,也就是 10
(2)add 方法中的 x 乘以三倍等于 30,但是 main 方法中的 x 仍然等于 10。
(3)add 方法执行结束,参数 x 不再使用。
当方法参数为对象引用时,又是什么样的情况呢
package callbyvalue;
/**
* Java 总是按值调用
*
* @author 路人WL
* @date 2020/7/5
*/
public class TestCallByValue {
public static void addAge(Person person) {
person.setAge(person.getAge() + 10);
}
public static void main(String[] args) {
Person p = new Person("小明", 20);
addAge(p);
System.out.println(p.getAge());
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
来看一下调用 addAge 方法具体的执行过程:
(1)方法 addAge 的方法参数变量 person 得到的是 main 方法的 p 的对象引用拷贝值。
(2)p 与 person 指向同一个 Person 对象。
(3)在 addAge 中调用 set 方法修改 age 值。
(4)方法结束后,变量 person 不再使用。
三、总结
方法参数有两种,基本数据类型和对象引用。
当方法参数为基本数据类型时,传递的是值的拷贝。
当方法参数为对象引用时,传递的是对象引用值的拷贝。
所以,Java 只有值传递。
Java 方法参数的使用情况(来自 《Java 核心技术卷 1》p120):
- 一个方法不能修改一个基本数据类型的参数。
- 一个方法可以改变一个对象参数的状态。
- 一个方法不能让对象参数引用一个新的对象。