网络文章

用画小狗的方法来解释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还是绑在旺财身上,这也就解释了,为什么执行完方法出来

原创不易,完成人机校验,阅读全文

相关推荐