看板 java 關於我們 聯絡資訊
※ 引述《tzk28419 (甲鳥)》之銘言: : 麻煩各位了 : 今天腦子打結 : 有關這個程式的輸出值 : public class Student{ : public int id; : } : public static void change(Student x){ : x.id=102; : } : public static void main (String[] args){ : Student s1=new Student(); : s1.id=101; : change(s1); : System.out.println(s1.id); : } : 如果Java中全部都是call by value來看的話 : 印出的結果應該是101才對 : 可是為什麼答案是102呢? : 而且在x.id=102;前面多加x=new Student();就會和我起先想的一樣是101 : 這兩者我以後要如何分別呢? : 流程是怎樣跑的? 看在推文中也有站友說不明白,我嘗試解釋一下。 首先,Java只有 pass-by-value (在這版戰過很多 次了,這說法連 JLS 自己也是這樣說,我不希望又 執著這個話題又有戰火了) 首先為免詞語混淆,我先把一個 Java 裡常用的字改 一改名。Java 裡常說到非 primitive type 的 var 就是 reference type。在這篇中我把這個名詞改為 Pointer (有 C/C++ 經驗的,就把它常成 C/C++ 裡 的 pointer 吧)。因為這個 "reference" 和 "pass by reference" 放在一起經常讓人眼花。 常說 Java 只有 Pass-by-value,而原 po 例子中, Student 明明沒有 pass-by-value,為什麼? 首先要記著,一個非 primitive 的 var, 它就是 pointer。 即是, Student s1=new Student(); 裡面,s1 本身不是一個 Student 的 Object, 它是 Student 的 Pointer, 它只是指向一個 Student 的 Object 而已。 明白了這,一切都好解說了。 change(s1) 的確是 pass-by-value。可是要記著,傳進 change() 的,不是一個 Student 的 Object,而是一個 Student 的 pointer,所以,被拷貝了一份的,是 pointer 而非 student 的 object. 用圖解說一下吧: 你的第一個情況 Student s1 = new Student() +------------+ s1 [0x12345678] ------------> | Student | | - id: 0 | +------------+ Student s1 = new Student() s1.id = 101; +------------+ s1 [0x12345678] ------------> | Student | | - id: 101 | +------------+ Student s1 = new Student() s1.id = 101; change(s1) change(x) { +------------+ s1 [0x12345678] ------------> | Student | +-> | - id: 101 | | +------------+ | x [0x12345678] ------------+ Student s1 = new Student() s1.id = 101; change(s1) change(Student x) { x.id = 102; +------------+ s1 [0x12345678] ------------> | Student | +-> | - id: 102 | | +------------+ | x [0x12345678] ------------+ Student s1 = new Student() s1.id = 101; change(s1) change(Student x) { x.id = 102; } s.id +------------+ s1 [0x12345678] ------------> | Student | +-> | - id: 102 | | +------------+ | x [0x12345678] ------------+ 完結後, s1.id 當然拿到 102. 好了,第二個情況,你加了 x = new Student(),到這步為 止和第一情況都一樣: Student s1 = new Student() s1.id = 101; change(s1) change(Student x) { +------------+ s1 [0x12345678] ------------> | Student | +-> | - id: 101 | | +------------+ | x [0x12345678] ------------+ Student s1 = new Student() s1.id = 101; change(s1) change(Student x) { x = new Student(); +------------+ s1 [0x12345678] ------------> | Student | | - id: 101 | +------------+ +------------+ x [0x98765432] -------------> | Student | | - id : 0 | +------------+ Student s1 = new Student() s1.id = 101; change(s1) change(Student x) { x = new Student(); x.id = 102; } +------------+ s1 [0x12345678] ------------> | Student | | - id: 101 | +------------+ +------------+ x [0x98765432] -------------> | Student | | - id : 102 | +------------+ change 完結後,s1 當然還是拿到 101 應該清楚了吧? Alien -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 223.19.42.175 ※ 編輯: adrianshum 來自: 223.19.42.175 (05/25 23:57)
swpoker:只能推了 05/25 23:58
wannawanna:推圖解說明 05/26 00:38
andymai:其實講到pointer pass by value就該懂了~大大還用心畫了圖 05/26 07:26
tzk28419:我懂了!!謝謝Alien!!超棒的圖!!!! 05/26 08:44
kaocoming:推推!!!!! 05/26 09:34
Expsun:用心給推! 05/26 10:05
tails32100:推用心畫>< 05/26 10:10
aiueoH:推~ 05/26 13:15
aiueoH:不知道可否順便問一下 C# 是不是也是如此? 05/26 13:19
fonz:畫圖畫的很用心XD~ 大推 05/26 15:34
hotscott:推推!! 清楚~ 05/26 18:20
KanoLoa:這類問題都會讓我慶幸以前C有學過point 05/26 19:46
a88258850:感謝~ 05/26 22:06
nhtyjm:用心推 05/27 00:16
adrianshum:KanoLoa: 是 pointer, 不是 point 05/27 06:55
adrianshum:aiueoH: 只看過 C# 的皮毛,C# 不是以 primitive/ref 05/27 06:56
adrianshum:作分野,而是根據忘了什麼規定去決定傳的是 pointer 05/27 06:57
adrianshum:還是obj 本身。不過只要傳的是 pointer, 概念也一樣 05/27 06:57
KanoLoa:XD 05/27 08:40
abola921:推! 少見的圖解法 05/27 10:17
aiueoH:謝謝 adrianshum ~ 瞭解 05/27 10:49
gmoz:清楚明白 05/27 12:41
PsMonkey:樓上讓我想到《奪命金》 XD 05/27 12:57
brianhsu:推圖解~ 05/27 14:47
coolcomm:推 05/27 20:45
swpoker:其實這個在j2se的官方教學書冊裡面就有了 05/28 13:36
lsunyu:疑 第10頁上面第一個位置為什麼id拿到了102? 05/28 22:35
issuemylove:pass-by-value 05/29 16:10
lsunyu:可是第10頁不是還在x = new Student(); 階段 id=102? 05/30 00:46
adrianshum:樓上:明顯是筆誤:P 改正中 06/01 22:43
※ 編輯: adrianshum 來自: 223.19.42.175 (06/01 22:45)
cn1754:推 06/02 23:28
qskyq0013:推推~ 06/11 20:25
silentduke:好文 專業圖解 06/11 23:53
moonjuice:謝謝解惑。很清楚!! 06/22 01:35
kspacey:推 06/22 20:48