Java的引用传递?

149 阅读3分钟

说Java的引用传递之前,我们先来了解下什么是引用传递和值传递。

值传递

public class Test {
    public static void main(String[] args) {
        int x=100;
        System.out.println("调用方法前:"+x);//调用方法前:100;
        sum(x);
        System.out.println("调用方法后:"+x);//调用方法后:100;
    }
    private static void sum(int y) {
        y=1000;
    }
}

int x=100;这时候x的值为100。

sum(x);这时候x把的值复制了一份给了sum(int y)
y=1000这时候方法里y的值就从"100"变成了"1000"
方法结束时,方法出栈,x的值还是100。

小结

值传递,此传递就是将实参x的值复制一份给方法sum(int y)的形参y,形参的操作不会影响到实参。且当传递方法实参类型为基本数据类型(数字以及布尔值)时,是不可能实参数值的。

引用传递

我们先来看一段代码:

public class Test {
    public static void main(String[] args) {
        Car c=new Car("奔驰");
        System.out.println("调用方法前:"+c.name);//调用方法前:奔驰
        updateCar(c);
        System.out.println("调用方法后:"+c.name);//调用方法后:宝马
    }
    static void updateCar(Car a){
        a.setName("宝马");
    }
}

Car c=new Car("奔驰");这个时候c指向了堆内存中的对象。

updateCar(c);这时候我们把c的地址传递给a这时候ca指向同一对象。
我们在方法里调用了a.setName("宝马");那么这时候"奔驰"就变成了"宝马"。
a的作用域只在方法内存在,之后a会被回收。就变成了

小结

引用传递,把实参c的内存地址值给updateCar(Car a)方法的形参a,也就是说在方法执行时实参c和形参a指向的是同一内存地址,方法操作的是源数据,所以方法执行时会影响实参。当传递方法参数类型为引用数据类型时,一个方法将修改一个引用数据类型的参数所指向对象的值。

那么问题来了,Java真的有引用传递嘛?

public class Test {
    public static void main(String[] args) {
        Person x = new Person("赵", "10");
        Person y = new Person("孙", "20");
        System.out.println("方法调用前:x=" + x.toString());//方法调用前:x=Person{name='赵', age='10'}

        System.out.println("方法调用前:y=" + y.toString());//方法调用前:y=Person{name='孙', age='20'}
        change(x, y);
        System.out.println("方法调用后:x=" + x.toString());方法调用后:x=Person{name='赵', age='10'}
        System.out.println("方法调用后:y=" + y.toString());方法调用后:y=Person{name='孙', age='20'}
    }

    private static void change(Person x, Person y) {
        Person temp = y;
        y = x;
        x = temp;
        System.out.println("方法调用中:x=" + x.toString());方法调用中:x=Person{name='孙', age='20'}
        System.out.println("方法调用中:y=" + y.toString());方法调用中:y=Person{name='赵', age='10'}
    }
}

这时候你会发现引用xy的地址值并没有被调换。

        Person x = new Person("赵", "10");
        Person y = new Person("孙", "20");

这时候在堆内存创建对象。

之后调用方法change(x,y)
方法中的局部变量xy也指向了同样的内存地址。

        Person temp = y;
        y = x;
        x = temp;

这时候交换地址。

方法结束,方法出栈。
内存地址并为交换。

小结

实际上来说Java中并没有引用传递,都是值传递,只是在传递引用类型时,传递的值,是地址值。并没有传递引用。

引用传递

引用传递的话,在调用change(x,y)方法时内存中应该是这样

方法结束后,他们的互相调换了。
实际上JAVA并不存在这种形式!!!实际上JAVA并不存在这种形式!!!实际上JAVA并不存在这种形式!!!