按值传递的意义,使得函数对形参的赋值,不对外界造成副作用。
因此,给形参赋值通常是没有意义的。(参考《编程导论(Java)·2.4.3 final变量和不变类》-final变量 )
然而,既然对形参的赋值,不对外界造成副作用,需要的时候当然可以为形参赋值。
例如求[a,b]间自然数的和,我们通常会编写如下代码
public static int sum0(int a,int b){
int total=0;
for(int i=a;i<=b;i++){
total+= i;
}
return total;
}
你是否考虑一下,不要变量i?其实,i真的是多余的。
既然按值传递保护了我们,我们就应该直接对a进行++。
public static int sum(int a,int b){
int total=0;
for(;a<=b;a++){
total+= a;
}
return total;
}
学习按值传递,要知道它的表现、意义。你习惯第二种代码吗?
如果你的代码不是第二种,你还没有真正理解按值传递的意义。(其实,我本人就自然地使用i。大多数情况是我们没有注意这个问题,也没有人提到或告诉我这个问题)
所以,对按值传递的理解:
- 表现级。i=5,add(i)之后打印i,这种题可以正确解答;从函数的外界知道按值传递没有副作用。
- 书面级。简答题可以正确解答。知道按值传递的字面含义;
- 恍惚级。Java到底是按值传递还是按引用传递? 《Java编程思想》这本烂书,在这个问题上,也属于这个级别。它研究字面背后的东西,但是不得要领。
- 实践级。yqj2065希望我的学生习惯编写第二种代码。既然知道按值传递保护了我们,就应该按照正确的方式做事情。你为什么,或者说你是怎么想起,要使用(第一种代码中的)一个i的呢?我好不习惯啊
。
附:有人考虑比较a,b的大小,可以如下(注意,在介绍递归时,这是一个很好的反例。这个不是递归)
public static int sum(int a,int b){
if(a<=b){
int total=0;
for(;a<=b;a++){
total+= a;
}
return total;}
else return sum(b,a);
}