前言

今天逛论坛,遇到一个新手问引用传递的问题,特此记录。

问题是什么

我们先看一下遇到的问题是什么

User类只有一个属性
20190816161111830.png

public static void main(String[] args) {
        User user1 = new User();
        getUser(user1);
        System.out.println(user1);
    }
    private static void getUser(User user2) {
        User user3 = new User();
        user3.setName("a");
        user2 = user3;
    }

那么大家看看输出的结果中user1的name是空还是a呢?

到这里如果您知道为什么的话就不需要花费宝贵的时间往下看了

如果您和我有一样的疑问的话,请往下看,我们先不急着给出答案,来分析下值传递和引用传递

值传递

这里简单介绍一下值传递的原理,已经了解的可忽略看下面

public static void main(String[] args) {
        int x = 1;
        getNum(x);
        System.out.println(x);
    }
 
    private static void getNum(int y) {
        y = 2;
    }

这里显而易见x输出的值是1,那么怎么用jvm的变化来解释呢?

以下为内存图解:
2019081616553155.png

引用传递

public static void main(String[] args) {
        User user1 = new User();
        getUser(user1);
        System.out.println(user1);
    }
    private static void getUser(User user2) {
        user2.setName("a");
    }

在这种情况下明显user1的name变成了a

以下为内存图解:

在Java中,新创建的实体对象在堆内存中开辟空间,而引用变量在栈内存中开辟空间
20190816172413550.png

其中的@123为对象在堆中的地址,这里给随机值演示,并不真实是这个样子

其实引用传递本质上也是值传递,不过这个之传递的是引用对象的地址值。

最后,该看看我们最开始的问题出现在什么地方了

如果上面的引用传递你已经看懂的话,仔细考虑考虑也许就会明白了

我们一行一行代码来分析,看jvm做了什么:

User user1 = new User();

20190816173429752.png

第一句执行完后,栈中存储引用地址,堆中存储User实体对象

getUser(user1);
getUser(User user2)

20190816173642302.png

第二句执行调用getUser方法时,栈中开辟内存存储user2并将user1存储的地址复制给user2,所有此时user1和user2存储的是同一个地址,也就是指向同一个对象

User user3 = new User();
user3.setName("a");

20190816174437840.png

这里执行就不说了,看图

user2 = user3;

20190816174656453.png

这里就是问题所在,当将user3赋值给user2的时候,是将user3的引用地址赋值给user2,所以user2的地址已经变成了@456,当方法调用完毕,user2和user3都被回收,user1的值始终都没变!

感谢大家阅读,看到这里还不点个赞或者关注么,一起努力,共勉


版权声明:文章转载请注明来源,如有侵权请联系博主删除!
最后修改:2019 年 12 月 26 日 05 : 17 PM
如果觉得我的文章对你有用,请随意赞赏
评论打卡也可以哦,您的鼓励是我最大的动力!