为什么说Java中只有值传递?

1. 方法中参数的传递方式

我们都知道,在调用一个有参方法时,会把实际参数传递给形式参数,而这个传递的过程有两种方式,分别为值传递引用传递,它们的定义为:

  • 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对形式参数进行修改,将不会影响到实际参数。
  • 引用传递:指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对形式参数所进行的修改,将影响到实际参数。

由定义可知,值传递和引用传递的区别就在于:有没有创建副本值传递创建了副本,方法体中无法改变实际参数;引用传递没有创建副本,直接将实际参数的地址传递给了形式参数,方法体中可以改变实际参数。

2. 为什么说Java中只有值传递?

Java的数据类型分为基本类型和引用类型,很多人基于此认为:调用方法传递的参数是基本类型则为值传递,调用方法传递的参数是引用类型则为引用传递。

实际上真的如此吗?我们来看下面的几个例子。

当传递的参数为基本类型时:

public static void main(String[] args) {
    int sum = 10;
    System.out.println("修改前的sum值:"+sum);
    change(sum);
    System.out.println("修改后的sum值:"+sum);
}
public static void change(int sum) {
    sum = 20;
    System.out.println("形参num值:"+sum);
}

程序输出结果为:

修改前的sum值:10
形参num值:20
修改后的sum值:10

由结果可知,传递基本数据类型时,在函数中修改的仅仅是形参,对实参的值的没有影响。

当传递的参数为引用类型时:

public static void main(String[] args) {
    Person person = new Person(20, "张三");
    System.out.println("修改前:"+person);
    change(person);
    System.out.println("修改后:"+person);
}
public static void change(Person person) {
    person.setAge(30);
    person.setName("王五");
    System.out.println("形参person的值:"+person);
}

程序输出结果为:

修改前:Person{age=20, name='张三'}
形参person的值:Person{age=30, name='王五'}
修改后:Person{age=30, name='王五'}

由输出结果可知,实参的值竟然被改变了,那按照上面的引用传递的定义,实际参数的值被改变了,这不就是引用传递了么?

实际上,当传递的参数为引用类型时,程序传递的不是对象本身,而是对象的引用,它的值为对象的地址。所以,当传递的参数为引用类型时,要判断是否为引用传递,就要看传递的引用所指向的地址是否会被改变。

我们再来看下面的例子:

public static void main(String[] args) {
    Person person = new Person(20, "张三");
    System.out.println("修改前:"+person);
    change(person);
    System.out.println("修改后:"+person);
}
public static void change(Person person) {
	person =new Person();
    person.setAge(30);
    person.setName("王五");
    System.out.println("形参person的值:"+person);
}

为了显示的更形象,Person对象没有覆盖toString方法,程序输出的结果为:

修改前:main.test.Person@1540e19d
形参person的值:main.test.Person@677327b6
修改后:main.test.Person@1540e19d

由结果我们可以知道,person传递给形参的只是一个副本,在方法体里让形参引用新的对象,并没有改变person的地址值,所以本质上还是值传递。

有个比喻很形象,你传递的参数只是一把钥匙的复制品,方法拿着钥匙的复制品进入房间,不管对房间里的任何地方进行修改,或者修改钥匙的复制品,钥匙本身不会有任何改变。

所以说,Java中只有值传递。

posted @ 2020-10-28 16:16  渺渺孤烟起  阅读(184)  评论(0)    收藏  举报