Re: [問題] 新手程式流程問題

看板java作者 (Alien)時間11年前 (2013/05/25 23:54), 編輯推噓28(2807)
留言35則, 26人參與, 最新討論串2/2 (看更多)
※ 引述《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)

05/25 23:58, , 1F
只能推了
05/25 23:58, 1F

05/26 00:38, , 2F
推圖解說明
05/26 00:38, 2F

05/26 07:26, , 3F
其實講到pointer pass by value就該懂了~大大還用心畫了圖
05/26 07:26, 3F

05/26 08:44, , 4F
我懂了!!謝謝Alien!!超棒的圖!!!!
05/26 08:44, 4F

05/26 09:34, , 5F
推推!!!!!
05/26 09:34, 5F

05/26 10:05, , 6F
用心給推!
05/26 10:05, 6F

05/26 10:10, , 7F
推用心畫><
05/26 10:10, 7F

05/26 13:15, , 8F
推~
05/26 13:15, 8F

05/26 13:19, , 9F
不知道可否順便問一下 C# 是不是也是如此?
05/26 13:19, 9F

05/26 15:34, , 10F
畫圖畫的很用心XD~ 大推
05/26 15:34, 10F

05/26 18:20, , 11F
推推!! 清楚~
05/26 18:20, 11F

05/26 19:46, , 12F
這類問題都會讓我慶幸以前C有學過point
05/26 19:46, 12F

05/26 22:06, , 13F
感謝~
05/26 22:06, 13F

05/27 00:16, , 14F
用心推
05/27 00:16, 14F

05/27 06:55, , 15F
KanoLoa: 是 pointer, 不是 point
05/27 06:55, 15F

05/27 06:56, , 16F
aiueoH: 只看過 C# 的皮毛,C# 不是以 primitive/ref
05/27 06:56, 16F

05/27 06:57, , 17F
作分野,而是根據忘了什麼規定去決定傳的是 pointer
05/27 06:57, 17F

05/27 06:57, , 18F
還是obj 本身。不過只要傳的是 pointer, 概念也一樣
05/27 06:57, 18F

05/27 08:40, , 19F
XD
05/27 08:40, 19F

05/27 10:17, , 20F
推! 少見的圖解法
05/27 10:17, 20F

05/27 10:49, , 21F
謝謝 adrianshum ~ 瞭解
05/27 10:49, 21F

05/27 12:41, , 22F
清楚明白
05/27 12:41, 22F

05/27 12:57, , 23F
樓上讓我想到《奪命金》 XD
05/27 12:57, 23F

05/27 14:47, , 24F
推圖解~
05/27 14:47, 24F

05/27 20:45, , 25F
05/27 20:45, 25F

05/28 13:36, , 26F
其實這個在j2se的官方教學書冊裡面就有了
05/28 13:36, 26F

05/28 22:35, , 27F
疑 第10頁上面第一個位置為什麼id拿到了102?
05/28 22:35, 27F

05/29 16:10, , 28F
pass-by-value
05/29 16:10, 28F

05/30 00:46, , 29F
可是第10頁不是還在x = new Student(); 階段 id=102?
05/30 00:46, 29F

06/01 22:43, , 30F
樓上:明顯是筆誤:P 改正中
06/01 22:43, 30F
※ 編輯: adrianshum 來自: 223.19.42.175 (06/01 22:45)

06/02 23:28, , 31F
06/02 23:28, 31F

06/11 20:25, , 32F
推推~
06/11 20:25, 32F

06/11 23:53, , 33F
好文 專業圖解
06/11 23:53, 33F

06/22 01:35, , 34F
謝謝解惑。很清楚!!
06/22 01:35, 34F

06/22 20:48, , 35F
06/22 20:48, 35F
文章代碼(AID): #1HeDx0m0 (java)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1HeDx0m0 (java)