所以我在读这个帖子 https://stackoverflow.com/questions/40480/is-java-pass-by-reference和回复编号。 2. 在该示例中,调用该方法后,地址 42、name 处的 Dog 值是否更改为 Max?
Dog myDog;
Dog myDog = new Dog("Rover");
foo(myDog);
public void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
Java是按值传递的——always,对于基元和对象都是如此。
对于对象来说,传递的是对堆上对象的引用。方法在传入时无法更改该引用所指向的内容。
如果该引用指向具有可变数据的对象,则该方法可以更改其状态。
来自 Ken Arnold 和 James Gosling 所著的《Java 编程语言第二版》(ISBN 0-201-31006-6)(可能从第 40 页开始——现在手边没有这本书):
有些人会错误的说Java中的对象是“pass by
引用。”术语“通过引用传递”正确地表示当
参数被传递给函数,被调用的函数得到一个
引用原始值,而不是其值的副本。如果
函数修改其参数,调用代码中的值将是
更改是因为参数和形参使用相同的槽
记忆。 [...]Java中只有一种参数传递模式——pass
按价值——这有助于让事情变得简单。
那么让我们看一下您的示例(有一些改进):
public class Dog {
private String name;
public static void main(String [] args) {
Dog myDog = new Dog("Rover");
System.out.println("before foo: " + myDog);
foo(myDog);
System.out.println("after foo: " + myDog);
}
public static void foo(Dog someDog) {
someDog.setName("Max"); // AAA
someDog = new Dog("Fifi"); // BBB
someDog.setName("Rowlf"); // CCC
}
public Dog(String n) { this.name = n; }
public String getName() { return this.name; }
public void setName(String n) { this.name = n; }
public String toString() { return this.name; }
}
这是输出:
before foo: Rover
after foo: Max
Tool completed successfully
您无法更改传递给的引用foo
指向,因此将其设置为 BBB 行名称为“Fifi”的引用,然后在 CCC 行更改该对象的名称,不会执行任何操作。该实例有资格进行垃圾收集,当foo
exits.
指向“Rover”的传入引用有一个可变数据成员:它的名称。在 AAA 行更改其值会反映在传入的引用中;因此输出不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)