用画小狗的方法来解释Java中的值传递
在开始看我画小狗之前,咱们先来看道很简单的题目: 下面程序的输出是什么?Dog myDog = new Dog("旺财");changeName(myDog);System.out.println(myDog.getName());public void changeName(dog) {
在开始看我画小狗之前,咱们先来看道很简单的题目:
下面程序的输出是什么?
Dog myDog = new Dog("旺财");
changeName(myDog);
System.out.println(myDog.getName());
public void changeName(dog) {
dog.setName("小强");
}如果你的回答是“小强”,好,恭喜你答对了。下面我们改一下代码:
Dog myDog = new Dog("旺财");
changeName(myDog);
System.out.println(myDog.getName());public void changeName(dog) {
dog = new Dog();
dog.setName("小强");
}是的,我只是在changeName方法里面加了一句代码
dog = new Dog();1
这一次的输出又是什么呢?
A旺财
B小强
答案是 A旺财,changeName方法并没有把myDog的名称改了。如果你答错了,没关系,我要开始画小狗了,画完你就明白了;如果你答对了,但不太明白其中的原因,那我画的小狗也肯定能帮到你。
myDog是什么
首先你要搞懂,代码里的变量myDog是什么?myDog真的就是一只狗吗?不!不是!myDog只是一条遛狗用的狗绳!
换句话说说,myDog并不是new出来的放在堆中的对象(object)!myDog只是一个指向这个对象实例的引用(reference)!如果你对Java的运行时数据区域足够了解,应该知道,这个引用是放在虚拟机栈上的。
参数传递
现在你知道了,myDog只是一条绳子,但这似乎并不能解释为什么changeName方法没有把myDog的名称改为“小强”,因为按照现有的理解,dog = new Dog(),就是把我的狗绳绑到另一只小狗身上,然后给这只小狗起名为“小强”,就像这样:
可事实是,myDog还是叫旺财,这是为什么?
问题就出在方法调用上,当我执行changeName(myDog)这一行代码时,myDog这条狗绳,被复制了一份,而传入到changeName方法里的那条狗绳(dog),就是复制出来的那一条,就像这样:
接着执行dog= new Dog(),这一行代码,就是把复制出来的那一条狗绳,从myDog解绑,重新绑到new出来的那只小狗上,也就是后来被起名为“小强”的小狗:
而myDog还是绑在旺财身上,这也就解释了,为什么执行完方法出来
原创不易,完成人机校验,阅读全文