java 板


LINE

非常感谢大家的热心回应,我完全理解了 现在只剩一个小问题想问... ex1: String a = "Hello"; a = "kdok123"; 这个结果是new了两个String的空间在Heap ex2: Interger a = 3; a = 4; 结果是new了一个Interger的空间在Heap,a指向的值从3改成了4 以上两个例子体现了String的不可变性 请问例子的观念是对的吗? 另外还有一个小疑惑:为什麽java要定义String的不可变性呢? 除了不断的增加heap和GC的负担之外我想不到其他好处欸... --------------------------------------------------------- 补充:想了一下我好像还没完全理解 以dark大&Chikei大的观念来看我的ex1: 输出两次会是一样的原因是因为String的不可变性 "所以str2指向的地方因为不可改变,只能另外再开一个空间去存新的值" 但以这样的观念把String改成Integer,似乎就应该得到改变过後的结果 (因为Integer可以变) 但实际测试发现Interger得到的结果也是两个一样的输出 到底是为什麽呢? 2次补充: java的所有 primitive wrapper class都是 immutable的 https://en.wikipedia.org/wiki/Primitive_wrapper_class 所以这样观念就完全通了 补充一点: 上面所有提到call by value的大大, java只有call by value是没错的 但如果是以String或是Integer传入的value会是address,而不像一般传入primitive 的value 所以ex1的call by value会新复制一个address指向本来的位置, 这个时候的修改应该是可以成功的 但因为此时Immutable的特性,所以会新开一份空间来存值,才保留了原本的值 若没有这样的特性,值是会变的,跟call by value没有关系 以上是我整理的观念,若有错误烦请讨论指正 再次感谢大家的热心回应!



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 60.250.185.98
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/java/M.1418904044.A.327.html ※ 编辑: kdok123 (60.250.185.98), 12/18/2014 20:12:09 ※ 编辑: kdok123 (60.250.185.98), 12/18/2014 20:15:14
1F:→ Kenqr: 输出2次一样是因为pass by reference,和不可变无关 12/18 20:26
2F:→ Kenqr: ex2的a会指到另一个不同的位置,用任何class都会这样 12/18 20:28
3F:→ ssccg: 你根本没有懂,就说你的结果跟不可变性"完全"没关系 12/18 20:33
4F:→ ssccg: String不可变是String不提供任何方法修改它里面char array 12/18 20:34
5F:→ ssccg: 存的值,要修改一定是产生新的String object 12/18 20:35
※ 编辑: kdok123 (61.221.50.98), 12/18/2014 20:49:04
6F:→ ssccg: 刚进method的str2指向的就是完全同一个String 12/18 20:39
7F:→ ssccg: 并没另外开一个空间,是之後你自己开新的空间放新的String 12/18 20:40
8F:→ ssccg: ="abc"相当於=new String(new char[] {'a','b','c'}) 12/18 20:43
9F:→ ssccg: 可变性的意义在於如果有个MutableString class 12/18 20:44
10F:→ ssccg: 你可以用str2.setValue("abc")去改object的内容 12/18 20:45
11F:→ ssccg: 而不用写成str2 = new MutableString("abc") 12/18 20:45
12F:→ ssccg: 只要用的是 = new XXX(),不管哪个class都是一样的结果 12/18 20:47
13F:→ ssccg: 只要你用的是 = 都是不会变的,因为 = 不是改object里的值 12/18 20:52
14F:→ ssccg: 而是改reference指向的位址 12/18 20:52
15F:→ ssccg: 只有primitive type的时候用 = 才是改值 12/18 20:52
16F:→ kdok123: String="abc"的意思是若"String pool没有"abc",则创造 12/18 20:53
17F:→ kdok123: 一个新空间存放abc,否则指向abc 12/18 20:54
18F:→ kdok123: String ob = new String("abc")的意思是"不管String pool 12/18 20:55
19F:→ kdok123: 里有没有abc,都创造一个空间存放abc 12/18 20:55
20F:→ kdok123: 因为immutable的特性,才会造成上面的结果,否则任何的 12/18 20:56
21F:→ kdok123: 赋值动作都会覆盖原本的值 12/18 20:56
23F:→ ssccg: 覆盖原本的值也是覆盖reference,而不是覆盖value 12/18 20:57
24F:→ kdok123: 参考连结的观念的 12/18 20:57
25F:→ ssccg: 上面我简化没有考虑string pool的问题,但重点就是你用 = 12/18 20:57
26F:→ ssccg: 永远改不到原本那个object的值 12/18 20:57
27F:→ ssccg: 任何reference type变数的赋值动作(=)都只是改指向不同物件 12/18 20:59
28F:→ kdok123: 这边我认为是immutable的关系,若今天是mutable就改得到 12/18 21:02
29F:→ kdok123: 或许等我试试上面连结的atomic wrapper class? 12/18 21:02
30F:→ kdok123: android studio没有把那个class import进来不能测试... 12/18 21:03
31F:推 ssccg: 我是不知道你打算怎麽试,但是除了primitive的autowrapper 12/18 21:05
32F:→ ssccg: 还有String literal("...")以外,其他type都很清楚就是换了 12/18 21:06
33F:→ ssccg: 物件啊... 12/18 21:07
34F:→ ssccg: 如果你有学过C++,java的reference type基本上就是pointer 12/18 21:10
35F:→ ssccg: 如果是C++的pass by reference(&),即使物件是mutable 12/18 21:14
36F:→ ssccg: 还是可直接改caller func中那个reference的值(指向的位址) 12/18 21:15
37F:→ ssccg: 或是你可以去用C#试,C#的reference type跟java一样 12/18 21:17
38F:→ ssccg: String也是Immutable,但是方法可以pass by reference 12/18 21:17
39F:推 ssccg: 你的ex1用C# pass by ref版 http://ideone.com/Miptpm 12/18 21:23
40F:→ kdok123: Hi,因为java这边是auto-boxing的,所以以c++的观念来说 12/18 21:43
41F:→ kdok123: pointer是指向同一个地方,要修改值的 12/18 21:43
42F:→ kdok123: 但因为immutable的特性,才没有修改成功 12/18 21:43
43F:→ kdok123: 我只是想说,如果你认为java的reference就是c++的pointer 12/18 21:44
44F:→ kdok123: 那在auto-boxing的结果下,你应该会觉得值要被修改才对 12/18 21:45
45F:→ ssccg: immutable不是不能修改reference值,是不能修改object里面 12/18 23:20
46F:→ ssccg: 的data,你还是直接看上面的C#的范例... 12/18 23:22
47F:推 ssccg: 既然会C++也给你一个C++版 http://ideone.com/DSzyGI 12/18 23:37
48F:→ ssccg: 不是我觉得,是java的reference变数真的就是pointer 12/18 23:37
49F:→ ssccg: 改是改pointer指的位址,但是在call by value的时候改不动 12/18 23:38
50F:→ ssccg: caller func里面的pointer变数 12/18 23:38
51F:→ ssccg: 很明显就call by value/call by reference的差别啊.. 12/18 23:46
52F:→ ssccg: btw auto-boxing是指对只吃Object子class的地方(如list) 12/18 23:49
53F:→ ssccg: 自动包wrapper,unboxing是在assign给primitive变数的时候 12/18 23:50
54F:→ ssccg: 自动改为取值(.xxxValue)而不是assign reference 12/18 23:51
55F:→ ssccg: 如果全程都是直接用Integer这个class,那与一般class没差别 12/18 23:51
56F:→ ssccg: 把Integer assign给Integer变数是不会有auto-box/unbox行为 12/18 23:53
57F:推 bleed1979: 看完这整个讨论串,好难过,想去renew Java 7的认证。 12/19 07:28
58F:→ kdok123: 我很想讲得更清楚一点,但前面darkk6大已经画得很清楚了 12/19 09:22
59F:→ kdok123: 这边的重点应该是immutable/mutable的差别才对 12/19 09:22
60F:→ kdok123: 如果这边是mutable的class,你说的caller func的pointer 12/19 09:23
61F:→ kdok123: 变数就会被改到 12/19 09:24
62F:→ kdok123: 因为我认为这边的观念很重要,才会一直强调,或许其他 12/19 09:25
63F:→ kdok123: 版友可以加入一起讨论,来厘清这个问题? 12/19 09:25
64F:→ ssccg: 就算是mutable class,caller func的pointer还是不会改到 12/19 09:41
65F:→ ssccg: 因为是pass by value,在传入时只是复制pointer的值 12/19 09:42
66F:→ ssccg: d大的图我只能说 // 因为字串的 Immutable... 这句完全错误 12/19 09:43
67F:→ ssccg: 不管是什麽class,用assign (=)的方式,改的永远都是str2指 12/19 09:44
68F:→ ssccg: 向的位址(pointer value)而已,原本的那个object不会被动到 12/19 09:45
69F:→ ssccg: 要动原本的object就要用它的method/field 12/19 09:48
70F:→ ssccg: immutable意义在於原本的object没有公开的改值method/field 12/19 09:48
71F:→ ssccg: 用pointer来说的话就是要改object的值一定要先dereference 12/19 09:50
72F:→ ssccg: 用=只会改pointer存的位址 12/19 09:51
73F:→ ssccg: 你好像幻想lhs如果是个mutable reference type变数 12/19 10:05
74F:→ ssccg: 用=会自动把lhs指向的物件中代表value的field拿出来,然後 12/19 10:06
75F:→ ssccg: 把rhs expression物件中代表value的field里存的值放进去 12/19 10:07
76F:→ ssccg: 从你上面提auto-boxing可以看出来,可是实际上没这回事 12/19 10:10
77F:→ ssccg: =只会把lhs reference直接改成指向rhs的结果物件 12/19 10:11
78F:→ ssccg: lhs原本指向什麽完全没差,在=的动作中那个物件根本没出场 12/19 10:11
79F:→ ssccg: =只有在lhs是primitive type的时候才是赋值(因为primitive) 12/19 10:22
80F:→ ssccg: type才有所谓value,如果lhs是reference type,他指向的物 12/19 10:22
81F:→ ssccg: 件不一定有所谓的value,这时做的都只是改指向的物件 12/19 10:24







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灯, 水草

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

TOP