当前位置:网站首页>一个对象引用的思考
一个对象引用的思考
2022-08-04 05:03:00 【jvm77625】
一个有趣且令人困惑的代码片段
Code A:
final ConcurrentHashMap<String, Ref> REFS_MAPS = new ConcurrentHashMap<String, Ref>();
public void put(String key) {
Ref ref = new Ref(key, "1");
ref = new Ref(key, "2");
REFS_MAPS.put(key, ref);
}
public Ref get(String key) {
return REFS_MAPS.get(key);
}
它有可能会得到"1"吗?
错误的解释
在多线程调度的情况下,相同的 key 多次同时调用 put 和 get 方法,从 REFS_MAPS 方法 get 时,正好 put 运行到 Ref ref = new Ref(key, "1")
,所以就得到了“1”的值,如下所示:
这个解释是错误的,不会得到“1”。
REFS_MAPS
的 hash Node 存储指向 “ref” 对象的值,而不是对象引用。因此,当 ref 在 put()
方法时,ref 的 val 先指向堆中的“1”,后指向堆中的“2”,如下所示:
常见的困惑问题
将 put 方法改一下:
Code B:
public void put(String key) {
Ref ref = new Ref(key, "1");
REFS_MAPS.put(key, ref);
ref = new Ref(key, "2");
}
它有可能会得到"1"吗?
一定会是“1”,虽然 ref 的指向堆中的“2”,但是 REFS_MAPS 的 hash Node 存储指向 “ref” 对象的值还是“1”。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
再将 put 方法改一下:
Code C:
public void put(String key) {
Ref ref = new Ref(key, "1");
REFS_MAPS.put(key, ref);
ref.setValue("2");
}
它有可能会得到"1"吗?
不会的得到“1”,因为 ref 和 REFS_MAPS
存储的 “ref” 对象只指向的同一个值,当 ref 修改了值,REFS_MAPS 中 ref 的值也被修改了。
代码背后真正的意义是什么?
我们知道,值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,而 Java 只有值传递。
在 Code B 中,ref = new Ref(key, "2")
会重新开辟一片内存空间,赋值给 ref,后面的任何修改都不会改变 Ref ref = new Ref(key, "1")
的内容,这里不是引用传递,如果是引用传递的话,REFS_MAPS
中的引用也应该会改变,但是实际上并没有。
在 Code C 中,ref.setValue("2")
影响了 REFS_MAPS 中的值,因为这里是把 ref 的引用的地址复制了一份,传递给了 REFS_MAPS
。所以,ref 其实是值传递,把 ref 对象引用的地址当做值传递给了 REFS_MAPS
。
所以,值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。
边栏推荐
- Dynamic programming of the division of numbers
- C专家编程 第5章 对链接的思考 5.3 函数库链接的5个特殊秘密
- 有趣的 Kotlin 0x0E:DeepRecursiveFunction
- 中信证券网上开户怎么开的?安全吗?
- 深度学习21天——卷积神经网络(CNN):实现mnist手写数字识别(第1天)
- Mini program + e-commerce, fun new retail
- 少年成就黑客,需要这些技能
- go module的介绍与应用
- C Expert Programming Chapter 5 Thinking about Chaining 5.6 Take it easy --- see who's talking: take the Turning quiz
- 基于gRPC编写golang简单C2远控
猜你喜欢
Take care of JVM performance optimization (own note version)
【一步到位】Jenkins的安装、部署、启动(完整教程)
manipulation of file contents
将xml标签转换为txt(voc格式转换为yolo方便进行训练)
el-Select selector bottom fixed
10 Convolutional Neural Networks for Deep Learning 3
drools从下载到postman请求成功
drools from download to postman request success
3000字,一文带你搞懂机器学习!
如何简化现代电子采购的自动化?
随机推荐
图像处理之Bolb分析(一)
7. The principle description of LVS load balancing cluster
少年成就黑客,需要这些技能
Towards Real-Time Multi-Object Tracking (JDE)
How to dynamically add script dependent scripts
杭电多校-Slipper-(树图转化+虚点建图)
How to simplify the automation of modern e-procurement?
Get the selected content of the radio box
System design. Seckill system
C专家编程 第5章 对链接的思考 5.2 动态链接的优点
3000字,一文带你搞懂机器学习!
【技巧】借助Sentinel实现请求的优先处理
结构体函数练习
The 2022 PMP exam has been delayed, should we be happy or worried?
System design. How to design a spike system (full version transfer)
Will the 2023 PMP exam use the new version of the textbook?Reply is here!
【21天学习挑战赛】直接插入排序
Shocked, 99.9% of the students didn't really understand the immutability of strings
For Qixi Festival, I made a confession envelope with code
详解八大排序