锁定老帖子 主题:也谈Java值传递-到底传递了什么?
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-23
akiraray 写道 piao_bo_yi 写道 所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。 Java just pass by value…… 当然我本科时候的教科书上面写java还有引用传递……完全误人子弟 我觉得你没懂。 |
|
返回顶楼 | |
发表时间:2010-04-23
呵呵。受教了~
|
|
返回顶楼 | |
发表时间:2010-04-23
ironsabre 写道 akiraray 写道 piao_bo_yi 写道 所有东西都是值传递,但是这句话是废话。
JAVA,基本类型是值传递,其他是传递的引用的拷贝。 Java just pass by value…… 当然我本科时候的教科书上面写java还有引用传递……完全误人子弟 我觉得你没懂。 方法传参本质都是将值拷贝压堆栈,方法结束拷贝消失,c语言不也这样吗 java的引用我的理解就是不可计算的指针,但寻址寻值方式是和c没有区别的 本科书籍采购是有清单,如果清单的书都是烂书,也许你老师只能在烂书中 挑本好的,也不排除写书的人水平低或者作者认为本科生水平低写成这样 |
|
返回顶楼 | |
发表时间:2010-04-23
jiopi 写道 理解值传递当然重要!著名的双重检查锁定(double-checked-locking)问题根源就是值传递,volatile 锁定的也是 值 而不是 引用
双重检查锁定的根源是因为JVM 的优化导致乱序执行吧。。不知道你说的和值传递有什么关系?? |
|
返回顶楼 | |
发表时间: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语言指针抱起来看看吧! |
|
返回顶楼 | |
发表时间: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 的值锁定 解决了 双重检查锁定失效 的问题 |
|
返回顶楼 | |
发表时间:2010-04-23
你们都是说的付值吧!
付值当然是,有就引用,没有就创建了。 没有这个值它去引用什么? |
|
返回顶楼 | |
发表时间:2010-04-23
楼主似乎要杯具了,再投几票。。。
|
|
返回顶楼 | |
发表时间:2010-04-23
学习各位 的精华了
|
|
返回顶楼 | |
发表时间:2010-04-23
啊哦。。。。果真杯具了。。。。
|
|
返回顶楼 | |