最近在看 Martin Fowler 重构一书,在一章中看到 JS 参数传递是按值传递,联想到 Java。下面我们聊聊 Java 参数传递是值传递还是引用传递?
还记得初学 Java 的时候,同学就问我这个问题,我很自信的就回答当然是按值传递。然后用代码举了例子。
输出结果:
oldAge is 100
change age is 10
虽然同学认为我的例子没有问题,但是却不信服这个结论,举了另一个对象的例子,表示 Java 参数传递是引用传递。
程序输出结果:
dog in method name is fill
main method dog name is fill
的确这个例子改变了Dog对象 name 属性。当时看到之后,感觉打破了自己认知,难道 Java 传递真的按照引用的吗?不过这也不对,基本参数类型只有值,并不存在对象一说,难道 Java 对象(Object)按照用于传递,基本参数类型按照值传递?
不知道有没有小伙伴初学 Java 时有没有跟我有一样困惑?哈哈。
首先说明一下 Java 参数传递是按值传递,基本参数类型与对象是一样的。
对于这样的一个对象创建过程 Dog dog=new Dog("max");,实际上等式左边 dog 变量是只是一个引用,而等号右边才是真正对象,位于 JVM 堆上。
private static void foo(Dog foo) 在 foo 方法中声明名字为 foo 参数,在没有被调用之前,最初被赋值为null。
当调用 foo 方法之后,传入dog 变量,然后会将 dog实际指向对象的堆地址赋值给了 foo,将foo引用指向了实际参数对象。
然后在 foo方法中,改变了对象 name 属性。
由于 foo跟 dog 都引用同一个 Dog对象,所以输出 name 属性都为 fill。
下面再将举一个例子。
这个例子输出结果为:
dog in method name is fill
main method dog name is max
在这个例子中,在方法中创建一个新对象,然后 foo 将指向这个新对象。这里仅仅改变 foo 的引用。所以这就导致这个例子与第二个例子输出不一样。
总结
Java 参数传递是值传递。