在Java疑惑中通过引用传递

所以我正在阅读这篇文章并回复没有。 2.在该示例中,在调用该方法之后,Dog值是否在地址42处,name更改为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是按值传递的 – 总是 ,对于基元和对象都是如此。

对于对象,传递的东西是对堆上存在的对象的引用。 方法无法更改引用传入时引用的内容。

如果该引用指向具有可变数据的对象,则该方法可以更改其状态。

来自Ken Arnold和James Gosling的“Java编程语言第二版”(国际标准书号0-201-31006-6)(可能来自第40页 – 现在没有这本书的方便):

有些人会错误地说Java中的对象是“通过引用传递”。 术语传递正确意味着当一个参数传递给一个函数时,被调用的函数会获得对原始值的引用,而不是它的值的副本。 如果函数修改了其参数,则调用代码中的值将会更改,因为参数和参数在内存中使用相同的插槽。 […] Java中只有一个ParameterPassing模式 – 按值传递 – 这有助于简化操作。

那么让我们来看看你的例子(有一些改进):

 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退出时,该实例有资格进行垃圾收集。

指向“Rover”的传入引用具有可变数据成员:其名称。 在AAA行更改其值会反映在传入的引用中; 因此产出不同。

这可能是Java中大多数新手开发人员困惑的话题。 duffymo已经提供了一个详细的答案(我不打算重复),但我可以给你一些参考文章,希望能从你的脑海中清除疑惑。

Jon Skeet关于Java中参数传递的文章
传递价值请
Java是通过引用传递还是通过值传递?

HTH。

要求Dog(地址为42的那个)将他的名字改为Max

Dog的值是否在地址42, 名称的更改为Max?

是。 name改变了

 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 } 

myDogsomeDog共享同一个对象,并在开头包含相同的地址值。 也就是说,两个变量都告诉JVM如何到达内存中的Object Dog(堆)。 因此,如果你通过在someDog上调用setName方法来改变某些东西, myDog ‘会感觉到’效果!

someDog = new Dog("Fifi")创建一个新的Object Dog(Fifi), someDog变量包含一个新的Fifi值/地址。 也就是说, someDog的值someDog改变,并告诉JVM从现在开始如何到达Fifi。 此时, someDog上的每次更改都不会影响myDog

检查我在该post上的答案(带图片的那个)并注意我这次没有使用“指针”这个词,甚至没有使用“引用”这个词! ;)