JAVA只有传值调用(call by value)

  • 内容
  • 评论
  • 相关

目前程序设计语言中有关将参数传递给函数调用有两种方法,按值传递(call by value)和按引用传递(call by reference)(C语言中可以通过指针直接传递地址,和传引用效果类似)。因为我之前是学C++的,所以想当然认为JAVA也有这两种参数传递方式。可是看书之后才知道Java里只有传值调用,即在调用函数时,传递给形参的永远都是实参的副本,无论形参是基本数据类型(int,boolean)还是对象。

假设如果Java传递对象是按引用传递的,那么下列代码的结果应该是b,a。可是实际结果还是a,b,说明swap函数没有成功交换两个对象。

class Employee{
    private String name;
    public Employee(String name){
        this.name = name;
    }
    public void getName(){
        System.out.println(this.name);
    }
}

public class Study {
    public static void swap(Employee x, Employee y){
        Employee tmp;
        tmp = x;
        x = y;
        y = tmp;
    }
    public static void main(String[] args) {
        Employee a = new Employee("a");
        Employee b = new Employee("b");
        swap(a,b);
        a.getName();
        b.getName();
    }
}

但是如果按值调用,为什么能修改传入函数中对象的属性呢?如果之前有C/C++基础,从指针角度理解,很容易就想通了。先上一直我做的渣图。a、b为实参,x、y为形参,当调用swap()是,你可以理解Java新生成了a的值,并且将其赋值给了x,y亦然。然后这四个变量相当于四个指针,他们分别指向两块堆内存空间,如果修改对象属性,那么通过这个指向关系,通过成功修改堆内存空间里的内容,如果想交换对象,那么在函数内交换的只是形参的指向关系(如红色箭头所示),并不会影响到a、b对象的指向关系。

Java函数传递关系

总结:Java只有传值调用,函数调用不能修改基本数据类型参数的内容,可以修改对象参数的属性内容,不能修改对象参数的指向关系,即不能让对象参数引用到别的对象上去。