彻底搞懂Java传参到底是值传递还是引用传递

推理:

public class Phone{
    int price;
}

public class Main{
    public static void main(String[] args){
        Phone one = new Phone();
        one.price = 1000;
        
        changePrice(one);
        System.out.println(one.price);
    }

    public static void changePrice(Phone two){
        two = new Phone();
        two.price = 2000;

        System.out.println(one.price);
    }
}

我们来看一下运行结果:

显然,引用变量one所指向的对象并没有随着方法所做的改变而产生任何变化,也就是说:Java的传参是值传递(更好理解的讲,应

该叫副本传递,因为都是拷贝的副本)

如何证明上面这段话呢?

图片推理证实:

1.Phone one  = new Phone();//变量one引用地址(标为0x666)

2.one.price = 1000;//地址里存储成员变量的值

3.changePrice(one);  //拷贝变量one所引用的地址,传给变量two

4.two = new Phone();//变量two引用新的内存地址(标为0x777),注意看two指向的箭头断掉,并指向了新的地址区域,然而对

象one的指向没有发生任何变化,这是关键所在

Q:为什么通过这一步,就能证明变量one拷贝了一份引用地址传递给变量two呢?

A:如果变量one传递的是自己的地址本身,那么当变量two此时引用新的地址的话,变量one引用的地址也应该随着改变,然

而从代码的结果来看,变量one没有受到任何影响,也就是说变量one只是给了变量two一个拷贝

举个例子来解释一下:房东有一串钥匙,现在张三租房东的房,房东给张三配了把钥匙,张三和房东都住在房子里,但是如果张

三有一天买房了,那么张三就要搬走去住自己的房子了,此时房东就要收回钥匙。不过张三虽然搬走了,但房东肯定还是住在自

己的房子里的,不会去住张三的新房子

而如果变量one是直接把自己引用的地址给了变量two,那么就变成了房东和张三就只有一把钥匙,然后张三有钱了买了栋新房

子,还把房东的钥匙销毁了,迫使房东只能和自己住一起。

Q:但为什么去掉这段代码(即省去实例化过程),输出的结果显示one.price也变成了1000,这不就说明形参改变了实参,Java

中是有引用传递的吗?

    public static void changePrice(Phone two){
        //注释掉这行代码
        //two = new Phone();

        two.price = 2000;

        System.out.println(one.price);
    }

A:区分值传递还是引用传递的关键的确像你所说的,需要看形参是否改变了实参,但对于对象来说,地址才是实参!你发现地址

内存储的值发生了改变,但无法证明地址发生了改变,所以需要通过实例化的方式为变量two引用新的地址来证实地址变量one指

向的地址是否发生了变化!

(高亮的字引用于点击这里,是这篇博客点开了自己的思想灵感,感谢巨人)

再继续上面的例子来解释这个:房东是变量one,张三是变量two,房东的房子就是实参,房子内的家具就是地址内存储的值。张

三在租住期间改变了房子里的布局,但不能因为张三住过一段时间改变了布局,就说明张三在未来住到自己的房子的时候,房东

就不住他自己的房子而选择去住张三的新房子吧

结论

Java的参数传递是值传递,而平常我们在Java中所说的“引用传递”,实际上只是将引用对象的地址拷贝了一份传给形参,

而非自己本身的地址;否则,当我们为形参更换引用地址后,原拷贝方引用的地址(即为实参)也会发生变动

最后总结:

0.值传递和引用传递是针对传参来讲的

1.实例化的过程中,new的作用:分配一个区域,也就是说每new一个新对象就新分配一个区域

2.值传递的本质:传递的是拷贝,修改形参不会影响实参

3.引用传递的本质:传递的是本身,修改形参也会影响实参

4.对于基本数据类型来说:实参就是字面量

5.对于引用数据类型来说:实参是地址

6.Java中无论基本数据类型还是引用数据类型,传递的都是拷贝(一个是拷贝的字面量,一个是拷贝的地址),所以都是值传递

猜你喜欢

转载自blog.csdn.net/Marshallren/article/details/104764494