24
24
25
25
简单举个例子:
26
26
27
+ ```
27
28
public static void main(String[] args) {
28
- ParamTest pt = new ParamTest();
29
- pt.sout("Hollis");//实际参数为 Hollis
29
+ ParamTest pt = new ParamTest();
30
+ pt.sout("Hollis");//实际参数为 Hollis
30
31
}
31
32
32
33
public void sout(String name) { //形式参数为 name
33
- System.out.println(name);
34
+ System.out.println(name);
34
35
}
35
-
36
+ ```
36
37
37
38
实际参数是调用有参方法的时候真正传递的内容,而形式参数是用于接收实参内容的参数。
38
39
@@ -45,76 +46,77 @@ System.out.println(name);
45
46
> 引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
46
47
47
48
有了上面的概念,然后大家就可以写代码实践了,来看看Java中到底是值传递还是引用传递 ,于是,最简单的一段代码出来了:
48
-
49
+ ```
49
50
public static void main(String[] args) {
50
- ParamTest pt = new ParamTest();
51
+ ParamTest pt = new ParamTest();
51
52
52
- int i = 10;
53
- pt.pass(10);
54
- System.out.println("print in main , i is " + i);
53
+ int i = 10;
54
+ pt.pass(10);
55
+ System.out.println("print in main , i is " + i);
55
56
}
56
57
57
58
public void pass(int j) {
58
- j = 20;
59
- System.out.println("print in pass , j is " + j);
59
+ j = 20;
60
+ System.out.println("print in pass , j is " + j);
60
61
}
61
-
62
+ ```
62
63
63
64
上面的代码中,我们在pass方法中修改了参数j的值,然后分别在pass方法和main方法中打印参数的值。输出结果如下:
64
65
66
+ ```
65
67
print in pass , j is 20
66
68
print in main , i is 10
67
-
69
+ ```
68
70
69
71
可见,pass方法内部对name的值的修改并没有改变实际参数i的值。那么,按照上面的定义,有人得到结论:Java的方法传递是值传递。
70
72
71
73
但是,很快就有人提出质疑了(哈哈,所以,不要轻易下结论咯。)。然后,他们会搬出以下代码:
72
-
74
+ ```
73
75
public static void main(String[] args) {
74
- ParamTest pt = new ParamTest();
76
+ ParamTest pt = new ParamTest();
75
77
76
- User hollis = new User();
77
- hollis.setName("Hollis");
78
- hollis.setGender("Male");
79
- pt.pass(hollis);
80
- System.out.println("print in main , user is " + hollis);
78
+ User hollis = new User();
79
+ hollis.setName("Hollis");
80
+ hollis.setGender("Male");
81
+ pt.pass(hollis);
82
+ System.out.println("print in main , user is " + hollis);
81
83
}
82
84
83
85
public void pass(User user) {
84
- user.setName("hollischuang");
85
- System.out.println("print in pass , user is " + user);
86
+ user.setName("hollischuang");
87
+ System.out.println("print in pass , user is " + user);
86
88
}
87
-
89
+ ```
88
90
89
91
同样是一个pass方法,同样是在pass方法内修改参数的值。输出结果如下:
90
-
92
+ ```
91
93
print in pass , user is User{name='hollischuang', gender='Male'}
92
94
print in main , user is User{name='hollischuang', gender='Male'}
93
-
95
+ ```
94
96
95
97
经过pass方法执行后,实参的值竟然被改变了,那按照上面的引用传递的定义,实际参数的值被改变了,这不就是引用传递了么。于是,根据上面的两段代码,有人得出一个新的结论:Java的方法中,在传递普通类型的时候是值传递,在传递对象类型的时候是引用传递。
96
98
97
99
但是,这种表述仍然是错误的。不信你看下面这个参数类型为对象的参数传递:
98
-
100
+ ```
99
101
public static void main(String[] args) {
100
- ParamTest pt = new ParamTest();
102
+ ParamTest pt = new ParamTest();
101
103
102
- String name = "Hollis";
103
- pt.pass(name);
104
- System.out.println("print in main , name is " + name);
104
+ String name = "Hollis";
105
+ pt.pass(name);
106
+ System.out.println("print in main , name is " + name);
105
107
}
106
108
107
109
public void pass(String name) {
108
- name = "hollischuang";
109
- System.out.println("print in pass , name is " + name);
110
+ name = "hollischuang";
111
+ System.out.println("print in pass , name is " + name);
110
112
}
111
-
113
+ ```
112
114
113
115
上面的代码输出结果为
114
-
116
+ ```
115
117
print in pass , name is hollischuang
116
118
print in main , name is Hollis
117
-
119
+ ```
118
120
119
121
这又作何解释呢?同样传递了一个对象,但是原始参数的值并没有被修改,难道传递对象又变成值传递了?
120
122
@@ -143,30 +145,30 @@ print in main , name is Hollis
143
145
但是,不管上面那种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了。那你说你会不会受到影响?而我们在pass方法中,改变user对象的name属性的值的时候,不就是在“砸电视”么。
144
146
145
147
还拿上面的一个例子来举例,我们` 真正的改变参数 ` ,看看会发生什么?
146
-
148
+ ```
147
149
public static void main(String[] args) {
148
- ParamTest pt = new ParamTest();
150
+ ParamTest pt = new ParamTest();
149
151
150
- User hollis = new User();
151
- hollis.setName("Hollis");
152
- hollis.setGender("Male");
153
- pt.pass(hollis);
154
- System.out.println("print in main , user is " + hollis);
152
+ User hollis = new User();
153
+ hollis.setName("Hollis");
154
+ hollis.setGender("Male");
155
+ pt.pass(hollis);
156
+ System.out.println("print in main , user is " + hollis);
155
157
}
156
158
157
159
public void pass(User user) {
158
- user = new User();
159
- user.setName("hollischuang");
160
- user.setGender("Male");
161
- System.out.println("print in pass , user is " + user);
160
+ user = new User();
161
+ user.setName("hollischuang");
162
+ user.setGender("Male");
163
+ System.out.println("print in pass , user is " + user);
162
164
}
163
-
165
+ ```
164
166
165
167
上面的代码中,我们在pass方法中,改变了user对象,输出结果如下:
166
-
168
+ ```
167
169
print in pass , user is User{name='hollischuang', gender='Male'}
168
170
print in main , user is User{name='Hollis', gender='Male'}
169
-
171
+ ```
170
172
171
173
我们来画一张图,看一下整个过程中发生了什么,然后我再告诉你,为啥Java中只有值传递。
172
174
@@ -220,4 +222,4 @@ print in main , user is User{name='Hollis', gender='Male'}
220
222
[ 6 ] : http://www.hollischuang.com/wp-content/uploads/2018/04/pass3.png
221
223
[ 7 ] : https://en.wikipedia.org/wiki/Evaluation_strategy
222
224
[ 8 ] : http://chenwenbo.github.io/2016/05/11/%E5%85%B3%E4%BA%8E%E5%80%BC%E4%BC%A0%E9%80%92%E5%92%8C%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92/
223
- [ 9 ] : http://menzhongxin.com/2017/02/07/%E6%8C%89%E5%80%BC%E4%BC%A0%E9%80%92-%E6%8C%89%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92%E5%92%8C%E6%8C%89%E5%85%B1%E4%BA%AB%E4%BC%A0%E9%80%92/
225
+ [ 9 ] : http://menzhongxin.com/2017/02/07/%E6%8C%89%E5%80%BC%E4%BC%A0%E9%80%92-%E6%8C%89%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92%E5%92%8C%E6%8C%89%E5%85%B1%E4%BA%AB%E4%BC%A0%E9%80%92/
0 commit comments