java 板


LINE

※ 引述《sbrhsieh (偶尔想摆烂一下)》之铭言: : 实际上把 adrianshum 提出的例子改成 formal parameter: a 只有单纯的 : assignment 操作,还是会有人搞错,因此 adrianshum 的例子重点不在於 : Java String (某种程度来说)是 immutable object。 : 每次出现 call by reference/call by value 的讨论时,总是会出现许许多多 : 的 Java sample code,甚至 C/C++ 的 sample code,争论了半天认为 Java 是 : call by reference 到最後还是不能体会说 Java 只有 call by value 的人为 : 什麽会如此宣称。 闲闲没事,我又来了,这次我要学 adrianshum 来话图。 另外,其实我一直觉得宣称 Java 是 call by reference 根本就是 在误导……字串的那个例子就很明显了。 谜之声:如果觉得这字串只是特例,我还是觉得那麽一定是基础观念 不清楚啊!因为就算不是字串,还是可以造成相同效果滴。 class A { public int x = 5; } public class Test { void fun (A test) { test.x = 3; return; } public static void main (String [] args) { A test = new A (); fun (test); System.out.println ("test.x:" + test.x); } } 整个程式的流程是 main -> fun -> main,这应该很清楚,没有什特 别的,但问题是,每个一步下来,到底你的 reference、物件都放在 哪,生命周期有多长吗?如果可以回答的出来,其实管他是什麽型态 的物件,或是基本资料型态,都不会搞混的。 重点:真要说的话,Java 的 function 只有 call by value ,根本 就没有 call by reference 这一回事! 以下是流程: =================================================================== 1. A test = new A () // Heap 上长一个 A 物件,Stack 上长一个 // 名叫 test 的 reference 指到刚刚的 A Stack Heap +-------+ +--------+ main()| test | --------> | A{x=5} | +-------+ +--------+ ================================================================== 2. fun (test) // 这一步是重点,实际上是 stack 多了另一个 test, // 只是恰巧指到同一个物件啊! Stack Heap +-------+ fun() | test |----------------------------+ +-------+ +--------+ | main()| test | --------> | A{x=5} | <-----+ +-------+ +--------+ =================================================================== 3. test.x = 5 // 把 fun() 里的 test 指到的物件的 x 栏位改成 3 Stack Heap +-------+ fun() | test |----------------------------+ +-------+ +--------+ | main()| test | --------> | A{x=3} | <-----+ +-------+ +--------+ ==================================================================== 4. return // 这句有没有都没差,重点是 return 的时候最上层的 // test 立刻就消灭啦! Stack Heap +-------+ +--------+ main()| test | --------> | A{x=3} | +-------+ +--------+ ==================================================================== 5. System.out.println.... // 印出来的 test 指到的当然是 3 ==================================================================== 以上,是常见的『伪 call by reference』范例,但换下面这个例子就很清 楚了。 如果把 fun 改成像下面: void fun (A test) { test = new A(); test.x = 3 } 为什麽最後印出来的会是 5 而不是 3?因为在呼叫到 fun 的时候,记忆 体里是长这个模样的: ================================================================== 1. fun (test) // 这边一开始都一样 Stack Heap +-------+ fun() | test |----------------------------+ +-------+ +--------+ | main()| test | --------> | A{x=5} | <-----+ +-------+ +--------+ ================================================================== 2. test = new A(); // 现在 fun() 的 test 和 main() 的 test 指到的 // 根本是不同的物件啊! Stack Heap +-------+ +--------+ fun() | test |---------> | A{x=5} | +-------+ +--------+ main()| test | --------> | A{x=5} | +-------+ +--------+ ================================================================== 3. test.x = 3; // 把 fun() 的 test 指到的物件的 x 栏位改成 3 Stack Heap +-------+ +--------+ fun() | test |---------> | A{x=3} | +-------+ +--------+ main()| test | --------> | A{x=5} | +-------+ +--------+ ================================================================== 3. return; // fun() 的 test 被消灭了! // x = 3 的那个物件变孤儿,可以被 GC 回收 Stack Heap +--------+ | A{x=3} | // 我变垃圾了……囧! +-------+ +--------+ main()| test | --------> | A{x=5} | +-------+ +--------+ ================================================================== 4. System.out.pritnln... // main () 里的 test 指到的东西一 // 直都没变过,当然是 5 啊! ================================================================== 以上。 至於为什麽像是 adrianshum 指出的 void fun(String a) { a += "foo"; } 会产生和第二个 case 一样的状况,那就是因为 String 本身是不 可变的,所以上面的 function 可以视同(不完全正确)会被翻译 成: void fun(String a) { a = new String(......) } 没错,我们又把 a 指到另一个完全不同的物件!所以变成和上述 的第二个例子一样了。 -- ~ 白马带着她一步步地回到中原。白马已经老了,只能慢慢地走, 'v' Brian Hsu 但终是能回到中原的。江南有杨柳、桃花,有燕子、金鱼…… // \\ ( 坟 墓 ) /( )\ 但这个美丽的姑娘就像古高昌国人那样固执。 【白马啸西风】 ^`~'^ http://bone.twbbs.org.tw/blog 『那都是很好很好的,可我偏不喜欢。』 --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.120.199.114 ※ 编辑: brianhsu 来自: 59.120.199.114 (12/04 07:37) ※ 编辑: brianhsu 来自: 59.120.199.114 (12/04 07:37)







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP