Java 参数传递是值传递仍是引用传递?

最近在看 Martin Fowler 重构一书,在一章中看到 JS 参数传递是按值传递,联想到 Java。下面咱们聊聊 Java 参数传递是值传递仍是引用传递?bash

还记得初学 Java 的时候,同窗就问我这个问题,我很自信的就回答固然是按值传递。而后用代码举了例子。spa

passpyvalue.png

输出结果:code

oldAge is 100
change age is 10

复制代码

虽然同窗认为个人例子没有问题,可是却不信服这个结论,举了另外一个对象的例子,表示 Java 参数传递是引用传递。cdn

carbon65.png

程序输出结果:对象

dog in method name is fill
main method dog name is fill

复制代码

的确这个例子改变了Dog对象 name 属性。当时看到以后,感受打破了本身认知,难道 Java 传递真的按照引用的吗?不过这也不对,基本参数类型只有值,并不存在对象一说,难道 Java 对象(Object)按照用于传递,基本参数类型按照值传递?blog

不知道有没有小伙伴初学 Java 时有没有跟我有同样困惑?哈哈。it

首先说明一下 Java 参数传递是按值传递,基本参数类型与对象是同样的。io

对于这样的一个对象建立过程 Dog dog=new Dog("max");,实际上等式左边 dog 变量是只是一个引用,而等号右边才是真正对象,位于 JVM 堆上。class

image.png

private static void foo(Dog foo)foo 方法中声明名字为 foo 参数,在没有被调用以前,最初被赋值为null。变量

image.png

当调用 foo 方法以后,传入dog 变量,而后会将 dog实际指向对象的堆地址赋值给了 foo,将foo引用指向了实际参数对象。

image.png

而后在 foo方法中,改变了对象 name 属性。

image.png

因为 foodog 都引用同一个 Dog对象,因此输出 name 属性都为 fill。

下面再将举一个例子。

carbon66.png

这个例子输出结果为:

dog in method name is fill
main method dog name is max
复制代码

在这个例子中,在方法中建立一个新对象,而后 foo 将指向这个新对象。这里仅仅改变 foo 的引用。因此这就致使这个例子与第二个例子输出不同。

image.png

总结

Java 参数传递是值传递。