论坛首页 入门技术论坛

也谈Java值传递-到底传递了什么?

浏览 6370 次
该帖已经被评为新手帖
作者 正文
   发表时间: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中,没有 引用传递,只有值传递

   发表时间:2010-04-22  
说白了,基本类型在JVM 里是直接保存的,在栈内可以直接保存,而引用类型是保存一个可以被理解为是内存地址(但实际上应该不是内存地址值)的引用值,指向了堆。
还有Java 的引用只有一层传递。
就是说
Object a=new Object();
Object b=a;
Object c=b;

实际上是b->a;c->a
0 请登录后投票
   发表时间:2010-04-22  
真无聊, 传值/引用, 那么重要?这个口水话题怎么还死不完啊。
0 请登录后投票
   发表时间:2010-04-22  
理解值传递当然重要!著名的双重检查锁定(double-checked-locking)问题根源就是值传递,volatile 锁定的也是 值 而不是 引用
0 请登录后投票
   发表时间:2010-04-22  
·····好吧
0 请登录后投票
   发表时间:2010-04-22  
所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。
0 请登录后投票
   发表时间:2010-04-22  
piao_bo_yi 写道
所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。

Java just pass by value……
当然我本科时候的教科书上面写java还有引用传递……完全误人子弟
0 请登录后投票
   发表时间: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());
你再看看呢,值是不是变了。
0 请登录后投票
   发表时间: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而已。各位有兴趣研究的人,继续思考这个问题吧,我头晕得很,先退出去。
1 请登录后投票
   发表时间:2010-04-23  
到底是值传递还是引用传递已经没什么可讨论的了。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics