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/m.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燈, 水草

請輸入看板名稱,例如:Boy-Girl站內搜尋

TOP