论坛首页 入门技术论坛

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

浏览 6369 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-04-23  
akiraray 写道
piao_bo_yi 写道
所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。

Java just pass by value……
当然我本科时候的教科书上面写java还有引用传递……完全误人子弟


我觉得你没懂。
0 请登录后投票
   发表时间:2010-04-23  
呵呵。受教了~
0 请登录后投票
   发表时间:2010-04-23  
ironsabre 写道
akiraray 写道
piao_bo_yi 写道
所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。

Java just pass by value……
当然我本科时候的教科书上面写java还有引用传递……完全误人子弟


我觉得你没懂。


方法传参本质都是将值拷贝压堆栈,方法结束拷贝消失,c语言不也这样吗
java的引用我的理解就是不可计算的指针,但寻址寻值方式是和c没有区别的
本科书籍采购是有清单,如果清单的书都是烂书,也许你老师只能在烂书中
挑本好的,也不排除写书的人水平低或者作者认为本科生水平低写成这样
0 请登录后投票
   发表时间:2010-04-23  
jiopi 写道
理解值传递当然重要!著名的双重检查锁定(double-checked-locking)问题根源就是值传递,volatile 锁定的也是 值 而不是 引用


双重检查锁定的根源是因为JVM 的优化导致乱序执行吧。。不知道你说的和值传递有什么关系??
0 请登录后投票
   发表时间:2010-04-23  
没有想到这个问题还会引起这么多资深人士的口水。

其实很简单,如果大家先不想java的值传递和引用传递,c的传递大家应该都清楚吧,说穿了,所谓的引用传递不就是类似于c的指针吗?指针本身就是一个值,所以总的说来,java就是值传递。

Object a=new Object();
先创建了一个指向Object类型的引用对象 a.
再创建一个Object对象
然后将刚刚创建的Object对象的地址给a
这正如数据库的索引和表一样,一个索引项存储了指向某一行的实际地址。

Object b=a;
先创建了一个指向Object类型的引用对象 b.
然后将a的值(指向某一个对象的应用)复制传递一份给b
相当于又建立了一个索引项,该索引项存储的行地址和刚才那个索引项一样

b.set****()方法会引起a的属性的改变,因为两个都指向同一个地址。

b=new Object();
给b赋值了一个新的引用,现在b和a已经没有关系,对b的修改不会影响到a。



还不清楚的,建议好好把大学时候的c语言指针抱起来看看吧!


0 请登录后投票
   发表时间:2010-04-23  
zhxing 写道
双重检查锁定的根源是因为JVM 的优化导致乱序执行吧。。不知道你说的和值传递有什么关系??


我引入一个 olong 来解释对象的引用传递,就是不想 把 堆 栈 指针 等等 这些名词引入,因为本来Java也是打算回避这些问题的,但我认为就是因为 "对象是引用传递" 这个解释,很多本来可以简单理解的内容,被搞复杂了

因为 "对象是引用传递" 其实是两个层面:
1.对象变量(也就是我引入的olong类型)是值传递
2.传递的值代表的是 对象的"引用"

另外解释一下olong的命名原因:
不是因为我的参照对象是Long才叫olong的
而是我假设这个变量保存的也是一个long类型的数据(内存地址),只不过这个long的值表示的不是一个数字,而是一个对象的引用,当然,到底java是怎么保存对象变量的,我认为无需关心

就拿 volatile 来说吧,本来 synchronized 够用了

但 synchronized 被设计成了 引用 锁定,即 对 olong变量的值所指向的那个 对象 进行锁定

用olong解释,就是 如果 加锁对象的olong值相同 ,操作会被互斥,即使 是多个 olong 变量

这样问题就来了,synchronized 不能锁定 null ,即 如果 olong变量的值 指向的是 null (假设其值是-1)

这样一来 双重检查锁定 就出问题了

先回顾一下 代码吧
if (instance == null)// 1:instance的olong值为-1
  {
    synchronized(Singleton.class) {  
      if (instance == null)          //2:判断如果instance的olong值为-1
        instance = new Singleton();  //3: 给 instance的这个olong变量一个新的值,假设为0001
    }
  }

在多CPU的多线程环境里,因为优化,不同CPU在执行代码时,当涉及对instance的调用时,每个CPU都事先拿了instance的值的拷贝(再次值传递),假设不同CPU中的新olong为instance1 instance2 ,如果是调用对象的方法,自然不会出问题了,因为每个CPU拿到的值都相同

但在 双重检查锁定 中, 标注 3 的语句对 instance 这个olong进行了重新赋值,步骤应该是CPU1首先改写 instance1的值,然后再改写 instance 的值,但如果没有  volatile 值锁定,CPU2在CPU1解除Singleton.class锁定后运行到语句2时,本地拷贝 instance2 的值就可能还是 -1

于是双重检查锁定失效

所以 volatile 的值锁定 解决了 双重检查锁定失效 的问题
0 请登录后投票
   发表时间:2010-04-23  
你们都是说的付值吧!
付值当然是,有就引用,没有就创建了。
没有这个值它去引用什么?
0 请登录后投票
   发表时间:2010-04-23  
楼主似乎要杯具了,再投几票。。。
0 请登录后投票
   发表时间:2010-04-23  
学习各位 的精华了
0 请登录后投票
   发表时间:2010-04-23  
啊哦。。。。果真杯具了。。。。
0 请登录后投票
论坛首页 入门技术版

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