理解值传递和引用传递

首先,其实不管是值传递还是引用传递,其实都是值传递,都是副本。就像Think in Java里面说的:

I read in one book where it was “completely wrong to say that Java supports pass by reference,” because Java object identifiers (according to that author) are actually “object references.” And (he goes on) everything is actually pass by value. So you’re not passing by reference, you’re “passing an object reference by value.” One could argue for the precision of such convoluted explanations, but I think my approach simplifies the understanding of the concept without hurting anything (well, the language lawyers may claim that I’m lying to you, but I’ll say that I’m providing an appropriate abstraction).

上面的话其实就是在说,对于对象的形参而言,我们好像是在传递一个对象,然而实际上我们只是传递一个对象的引用(栈空间里)而不是对象本身(堆里的实际对象)。这里我们可以把其称为引用变量,引用变量和值变量都是值传递,都是副本。
这里写图片描述

如果以上还是理解不了大可以将方法参数接收分解为一系列赋值操作。

public class Ref{
    public static void main(String[] args){
      Person p = new Person();
      change(p);
    }
    public void change(Person p){//这里的p其实可以任意取名字,比如a,b,c....
       System.out.println(p);
    }
}

当调用change()时候可等效于这样一个过程:

public void change(Person person = p){//这里就是等效的过程
    System.out.println(person);
}

根据以上理解来看下这个示例:

public class Test{
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("123");
        change(str);
        System.out.println(str);
    }
    public static void change(StringBuffer str){
        str= new StringBuffer("abc");
    }
}

错误输出:abc
正确输出:123
等效过程:

public class Test{
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("123");
        change(str);
        System.out.println(str);
    }
    public static void change(StringBuffer str = str){//注意这里的等号左右的str并不是同一个str
        str = new StringBuffer("abc");
    }
}

当调用方法的时候,等号左边的是形参,右边的是你传入的,他们是两个引用变量,他们除了指向同一个对象,并没有其他关系,而在方法内

str = new StringBuffer("abc");

使得形参str指向了新的对象,但传入的str并没有改变。所以最后输出的时候还是123
结论:Java中都是值传递

猜你喜欢

转载自blog.csdn.net/chenbinkria/article/details/79822535