锁定老帖子 主题:也谈Java值传递-到底传递了什么?
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-22
java里面只有值传递,这是不变的真理,不过由于对象类型的特殊性,有些人还是会疑惑 值传递?还是 引用传递? 可能主要是这句话造成的: 在Java中方法参数的传递,对象是传递引用,基本数据类型是传递值。 如果java里面只有值传递,为何又要说对象是 引用传递?
对于 基本数据类型 是值传递,相信没有人会有疑惑。那对象到底传递了什么?
其实这源于JAVA在解释其变量类型时的一个混淆:JAVA里面只有8种基本数据类型和对象类型
于是便有了 基本数据类型是传递值,对象是传递引用
其实如果把对象类型也解释成一种 基本数据类型 ,那就不会出现 对象是传递引用 这句话让人疑惑的话了
下文将 对象类型 看成一种新的 基本类型, 姑且称之为 olong (object long),即 所有对象变量 都是 olong,虽然在java书写时可以写成具体的对象类型,如 Long a; 但其传递实质是 olong a;
让我们来重新认识 olong 吧:
赋值: long a = 1234; olong oa = new Long(1234); //Long oa = new Long(1234);
传递: long b = a; olong ob =oa; //Long ob = oa;
改变: b = 4321; ob = new Long(4321); //ob = new Long(4321);
改变了什么?: System.out.println(a); //输出 1234 System.out.println(b); //输出 4321 System.out.println(oa.longValue()); //输出 1234 System.out.println(ob.longValue()); //输出 4321
到底传递了什么: long: long a = 1234; //a的值1234 long b = a;//值传递 b的值1234;a的值1234 b = 4321;//b的值被改变为4321;但a不受影响,依然是1234
olong: long类型的变量保存和传递的是其指代的基本类型的值,那么olong呢? 可以认为olong类型的变量保存和传递的是一个指向具体对象的内存地址, olong oa = new Long(1234);//假设new Long生成的对象的地址为0001,则oa的值为0001 olong ob =oa; //值传递,ob的值0001;oa的值0001 ob = new Long(4321);//ob的值被赋予一个新的对象的地址,假设为0002,但oa的值不受影响,依然为0001 因此olong类型的赋值结果与long类型的表现一致,也是值传递
为什么对象是传递引用? 其实这句话也不错,因为olong变量本身就是一个引用,引用了一个对象(的内存地址) 但其实质是 值传递!只不过因为 olong 的值 还有一个 别名 叫做 引用,所以就被叫做了一个让人迷惑的新词:引用传递!
总结: olong的引入只是为了方便解释Java对象的值传递,说明在参数传递过程中,对象变量的传递和基本变量的传递是没有本质区别的,所以,在Java中,没有 引用传递,只有值传递! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-04-22
说白了,基本类型在JVM 里是直接保存的,在栈内可以直接保存,而引用类型是保存一个可以被理解为是内存地址(但实际上应该不是内存地址值)的引用值,指向了堆。
还有Java 的引用只有一层传递。 就是说 Object a=new Object(); Object b=a; Object c=b; 实际上是b->a;c->a |
|
返回顶楼 | |
发表时间:2010-04-22
真无聊, 传值/引用, 那么重要?这个口水话题怎么还死不完啊。
|
|
返回顶楼 | |
发表时间:2010-04-22
理解值传递当然重要!著名的双重检查锁定(double-checked-locking)问题根源就是值传递,volatile 锁定的也是 值 而不是 引用
|
|
返回顶楼 | |
发表时间:2010-04-22
·····好吧
|
|
返回顶楼 | |
发表时间:2010-04-22
所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。 |
|
返回顶楼 | |
发表时间:2010-04-22
piao_bo_yi 写道 所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。 Java just pass by value…… 当然我本科时候的教科书上面写java还有引用传递……完全误人子弟 |
|
返回顶楼 | |
发表时间:2010-04-22
对于在java里楼主这样的测试的想法就不对,
如果你这样 Bean a = new Bean(); a.setId(1) Bean b = a; b.setId(2); System.out.println(a.getId()); System.out.println(b.getId()); 你再看看呢,值是不是变了。 |
|
返回顶楼 | |
发表时间:2010-04-23
唉,搞了十多年Java了,最让我晕的就是这个话题了。
1、www.csdn.net上有一个叫做“钟声”的专家,有一本大作:《上班那点事儿》的,有一个博文就与这个有关的。http://blog.csdn.net/useway/archive/2009/09/14/4551049.aspx。当然,那里的主题是 Java中有没有指针。 Java中有没有指针呢?有,还是没有?可以有?还是不可以有?真的可以有?还是真的没有?可惜没几个相声演员懂程序,要不,是一段精彩的段子。 2、我原来有一个小兄弟,对这个话题也是乐此不疲,钻研了很久,还遍查资料,也写了不少文章。可以参考:http://jiangyongyuan.iteye.com/blog/593768、http://jiangyongyuan.iteye.com/blog/450687 到底是传值呢?还是传址呢?这是个问题?问问CPU吧,CPU也不知道,它就懂0/1而已。各位有兴趣研究的人,继续思考这个问题吧,我头晕得很,先退出去。 |
|
返回顶楼 | |
发表时间:2010-04-23
到底是值传递还是引用传递已经没什么可讨论的了。
|
|
返回顶楼 | |