一个随意list引发的惨案(java到底是值传递还是引用 传递?)
前两天写了一个递归,因为太年轻,把一个递归方法需要用到的list定义该递归方法外了,结果开始断点测试的时候有点小问题 ,然后上线之后因为数据量太多导致了一个java.util.ConcurrentModificationException异常,然后就debug。然后一顿操作因为单元测试的时候马虎出了点问题,以为新写的方法有问题,然后又一顿操作才发现在单元测试出了问题。最后成功解决问题,提交之后领导给我说:“你这个递归看起来还有问题哦?”,然后我心里一凉。然后领导再问:“你这个是值传递还是引用传递啊”我心中大惊,虽然我是一个新手,但是我看了几篇文章说java只有值传递的呀,但是大佬这么问我,我也不敢回答,害怕的一匹。然后偷偷查阅资料冷静分析java值传递还是引用传递。
先总结:
java中方法参数传递方式是按值传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
因为在平常使用中,我们在传递一个对象之后并不会在new一次该对象,如下图第三行所示,
所以方法内的对象和方法外的对象所指的内存是同一个地址(对象和list存放在堆中,方法内的数据存放在栈帧中,栈帧属于某个方法所有,方法结束后就销毁,而堆属于类),如果我们在方法内修改了该对象,在外面获取该对象也会改变,所以会被误认为是应用传递。如果在操作之前new一下,方法的对象指向和传递过来的对象指向就不是同一个地址了,所以我们在方法里面 操作了对象,方法外的对象也不会改变。如下图
那么问题来了,string类型是一个引用类型,然而我们操作他的时候和基础类是一样的,并没有引用传递的那种幻觉是为什么呢?
因为string不是基础类,它比较特殊,它是不可变类,每次我们操作它的时候就相当于new了一次。
其实会在java值传递和引用传递上不清楚的原因是基础不牢固。基础不牢固有两重一次,第一重是学的不牢固。第二重是基础原理(不懂jvm)不牢固。所以路漫漫其修远兮,吾将上下而求索呀。
如果想要详情了解值传递,就看下面这个文章,写的挺不错的。
https://blog.csdn.net/bntx2jsqfehy7/article/details/83508006
最新文章
- Java socket 多线程编程 示例
- uchome 2.0 存在持久XSS漏洞
- 触控(Touch) 、 布局(Layout)
- BIEE Setup
- 拉普拉斯特征图降维及其python实现
- ASP.NET页面之间传递值的几种方式(转载)
- tolua++实现lua层调用c++技术分析
- hdu 2046递推
- css属性详解
- CONTRO4 系列
- 线段树 by yyb
- Python文件读取常用方法
- jvm--深入理解java虚拟机 精华总结(面试)(转)
- 第36章:MongoDB-集群--Replica Sets(副本集)
- bzoj4310
- [转][MVC]更新 dll 后版本不匹配的问题
- 9.12 h5日记
- AngularJS实战之Controller之间的通信
- Xamarin iOS教程之申请付费开发者账号下载证书
- List集合实现简易学生管理