java 参数值_java初步—参数的值传递

校招季,本人匆匆忙忙地参加各种宣讲会,几次笔试下来都遇到同一个题目,而且全都错在同一想法上,方知自己的基础实在不太牢固,因此特别写在博客上提醒自己要脚踏实地地学习!不多说了,题目如下:

1 public classTest {2 public static voidmain(String[] args) {3 StringBuffer s1 = new StringBuffer("a");4 StringBuffer s2 = new StringBuffer("b");5 change(s1, s2);6 System.out.println(s1);7 System.out.println(s2);8 }9

10 private static voidchange(StringBuffer s1, StringBuffer s2) {11 s1.append(s2);12 s2=s1;13 }14 }

问题:请问最后打印出的结果是什么?

如果阅读我这篇随笔的是刚接触java(c#也行,java和C#在这方面基本一致)的同学,不妨不看后面的答案,自己做一下,也许会给你带来一些收获!

我在笔试的时候有四个选项:

A.a,b    B.ab,b    C.a,ab    D.ab,ab

很可能有不少人都会和我一样直接选择了选项D,不过很抱歉,这是一个绝对错误的答案,正确的答案是  B选项。

是不是也会有人和我刚开始一样觉得很奇怪呢?因为根据我们学到的知识,StringBuffer类型的变量是引用类型,也就意味着这个变量在change方法中的改变是会被保留下来的,那么s1,s2在change方法中都被改变了,为什么最后打印的时候只有s1是真正被改变了呢?

这个需要先知道一些基本的知识:

我们都知道在java中有基本数据类型和引用数据类型,他们在内存中的存储是不同的,基本数据类型诸如int,double之类的变量是直接把值存放在栈中的,而引用数据类型的变量是分为两部分进行存储的:第一部分和基本数据类型一致是存放在栈中的,第二部分是堆中。其中堆中存放的是这个变量真正的值,而栈中则是存放真正值的地址,就上面的题目来说,示意图如下:

e91cd7bd7bb880d3cc35be118174b596.png

图一

好了,如果知道变量的存储方式的话就可以往下了(如果不知道建议看看这方面专门的文章,我这篇说的不细)。

change方法中的参数名也是这题的障碍所在,因为名字和变量相同,会让人很容易进入陷阱,误认change方法中的参数s1,s1就是main方法中的变量s1,s2,我们不妨把参数名改一下,改后的代码如下:

1 public classTest {2 public static voidmain(String[] args) {3 StringBuffer s1 = new StringBuffer("a");4 StringBuffer s2 = new StringBuffer("b");5 change(s1, s2);6 System.out.println(s1);7 System.out.println(s2);8 }9

10 private static voidchange(StringBuffer a, StringBuffer b) {11 a.append(b);12 b=a;13 }14 }

注意第10行红色加粗的参数名,这样我们就可以绕开一点障眼法。

其实在这题中还是有个小问题的,那就是java中到底有没有引用传递的问题,如果是基本数据类型的话,如

1 int x=10;2

3 print(x);4

5 public voidprint(int y){6 System.out.println(y++);7 }

此时x作为print方法的参数,传递的是x真正的值,我们很容易知道在print方法中y的值是x值的复制,也就是说变量x只是把自己的值拷贝了一份给另外一个局部变量y,实质上二者没有任何关系,无论在print方法中y如何变化都不会影响x的值,这就是值传递了。而如果int x,y的类型改为Integer,此时变量都变为引用类型,x作为参数传递的就是x值的地址,那么y值在print方法中的改变就会反映到x的改变,这就是引用传递。

仔细想想,值传递和引用传递其实传递的都是作为参数的直接值(引用类型变量的直接值是真正值的地址),因此实质上说java只有值传递更为恰当。

解决了这个比较主观的问题之后,我们再来研究一下,引用类型变量s1,s2把地址传递给change方法之后,局部变量a,b就成为了s1,s2的别名(拥有相同的地址,指向了同一实例对象,只是名称不同而已,就和爸妈与老师叫你的称呼不一样),s1追加了s2的内容,所以变量s1的变化会被保留下来,最终打印的结果自然是“ab”,没有疑问。

重点来了,执行“a=b;”进行了变量的什么操作呢?

b63604f9d38fefa839d5a7ef49379538.png

图二

这样就可以清晰地看到,"b=a"这个操作实质只是把局部变量a的直接值(也就是真正值的地址)赋给了变量b,对于变量b的真正值没有任何的操作,所以对应变量s2的真正值没有任何变化,自然最后打印出来的结果是 “b".

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值