所以我正在阅读this post并回复否。 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
}
答案 0 :(得分:6)
Java是基于值的传递 - 总是,对于基元和对象都是如此。
对于对象,传递的东西是对堆上存在的对象的引用。方法无法更改引用传入时引用的内容。
如果该引用指向具有可变数据的对象,则该方法可以改变其状态。
来自“Java编程语言第二版”,作者Ken Arnold和James Gosling(国际标准书号0-201-31006-6)(可能来自第40页 - 现在没有这本书的方便):
有些人会错误地说Java中的对象是“通过的 参考。“通过引用传递的术语适当地表示当a 参数传递给函数,调用函数得到一个 引用原始值,而不是其值的副本。如果 函数修改其参数,调用代码中的值将是 因为参数和参数使用相同的插槽而更改 记忆。 [...] Java中只有一个ParameterPassing模式 - 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行更改该对象的名称,什么也没做。 <{1}}退出时,该实例有资格进行垃圾回收。
指向“Rover”的传入引用具有可变数据成员:其名称。在AAA行更改其值会反映在传入的引用中;因此产出不同。
答案 1 :(得分:2)
这可能是Java中大多数新手开发人员困惑的话题。 duffymo已经提供了一个详细的答案(我不打算重复),但我可以给你一些参考文章,我希望能从你的脑海中清除疑惑。
Jon Skeet关于Java中参数传递的article
Pass-by-Value Please
Does Java pass by reference or pass by value?
HTH。
答案 2 :(得分:1)
要求Dog(地址为42的那个)将他的名字改为Max
是
答案 3 :(得分:0)
地址42处的狗值,名称是否更改为最大值?
是。 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
}
答案 4 :(得分:0)
myDog
和someDog
共享同一个对象,并在开头包含相同的地址值。也就是说,两个变量都告诉JVM如何到达内存中的Object Dog(堆)。因此,如果您通过在setName
上调用someDog
方法来更改内容,myDog
'会感觉到'效果!
在someDog = new Dog("Fifi")
创建新的Object Dog(Fifi)后,someDog
变量包含Fifi的新值/地址。也就是说,someDog
的值会发生变化,并告诉JVM从现在开始如何到达Fifi。此时,someDog
上的每次更改都不会再影响myDog
。
检查我在该帖子上的答案(带图片的那个)并注意我这次没有使用“指针”这个词,甚至没有使用“引用”这个词! ;)