作者adrianshum (Alien)
看板java
标题Re: [问题] 新手程式流程问题
时间Sat May 25 23:54:38 2013
※ 引述《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)
1F:推 swpoker:只能推了 05/25 23:58
2F:推 wannawanna:推图解说明 05/26 00:38
3F:推 andymai:其实讲到pointer pass by value就该懂了~大大还用心画了图 05/26 07:26
4F:推 tzk28419:我懂了!!谢谢Alien!!超棒的图!!!! 05/26 08:44
5F:推 kaocoming:推推!!!!! 05/26 09:34
6F:推 Expsun:用心给推! 05/26 10:05
7F:推 tails32100:推用心画>< 05/26 10:10
8F:推 aiueoH:推~ 05/26 13:15
9F:→ aiueoH:不知道可否顺便问一下 C# 是不是也是如此? 05/26 13:19
10F:推 fonz:画图画的很用心XD~ 大推 05/26 15:34
11F:推 hotscott:推推!! 清楚~ 05/26 18:20
12F:推 KanoLoa:这类问题都会让我庆幸以前C有学过point 05/26 19:46
13F:推 a88258850:感谢~ 05/26 22:06
14F:推 nhtyjm:用心推 05/27 00:16
15F:→ adrianshum:KanoLoa: 是 pointer, 不是 point 05/27 06:55
16F:→ adrianshum:aiueoH: 只看过 C# 的皮毛,C# 不是以 primitive/ref 05/27 06:56
17F:→ adrianshum:作分野,而是根据忘了什麽规定去决定传的是 pointer 05/27 06:57
18F:→ adrianshum:还是obj 本身。不过只要传的是 pointer, 概念也一样 05/27 06:57
19F:推 KanoLoa:XD 05/27 08:40
20F:推 abola921:推! 少见的图解法 05/27 10:17
21F:推 aiueoH:谢谢 adrianshum ~ 了解 05/27 10:49
22F:推 gmoz:清楚明白 05/27 12:41
23F:推 PsMonkey:楼上让我想到《夺命金》 XD 05/27 12:57
24F:推 brianhsu:推图解~ 05/27 14:47
25F:推 coolcomm:推 05/27 20:45
26F:→ swpoker:其实这个在j2se的官方教学书册里面就有了 05/28 13:36
27F:推 lsunyu:疑 第10页上面第一个位置为什麽id拿到了102? 05/28 22:35
28F:推 issuemylove:pass-by-value 05/29 16:10
29F:推 lsunyu:可是第10页不是还在x = new Student(); 阶段 id=102? 05/30 00:46
30F:→ adrianshum:楼上:明显是笔误:P 改正中 06/01 22:43
※ 编辑: adrianshum 来自: 223.19.42.175 (06/01 22:45)
31F:推 cn1754:推 06/02 23:28
32F:推 qskyq0013:推推~ 06/11 20:25
33F:推 silentduke:好文 专业图解 06/11 23:53
34F:推 moonjuice:谢谢解惑。很清楚!! 06/22 01:35
35F:推 kspacey:推 06/22 20:48