我对Java还很陌生,但我在PHP方面有丰富的经验。当我编写Java程序时,我注意到变量不是我所期望的。
在Java中,所有方法参数都是按值传递的。然而,由于所有对象实际上都是引用,因此在传递对象时,您传递的是引用的值。这意味着如果您操纵传递到方法中的对象,则操作将保留。
这是什么意思?这是否意味着Java中的foo=blah
就像PHP中的$foo=&$blah
?如何在Java中只传递值?
我对Java还很陌生,但我在PHP方面有丰富的经验。当我编写Java程序时,我注意到变量不是我所期望的。
在Java中,所有方法参数都是按值传递的。然而,由于所有对象实际上都是引用,因此在传递对象时,您传递的是引用的值。这意味着如果您操纵传递到方法中的对象,则操作将保留。
这是什么意思?这是否意味着Java中的foo=blah
就像PHP中的$foo=&$blah
?如何在Java中只传递值?
class Foo {
private int bar;
public void setBar(int value) {
bar = value;
}
public int getBar() {
return bar;
}
}
public void doSomethingToFoo(Foo foo) {
foo.setBar(42);
}
更改 bar
将在调用处可见。这是一个持续的操作。对原始对象的引用被传递进去了。该对象的 setter 被调用,因此调用处的 getter 将返回 bar 的新值。
Foo foo = new Foo();
doSomethingToFoo(foo);
int bar = foo.getBar(); // gets 42
然而,鉴于
public void doSomethingElseWithFoo(Foo foo) {
foo = new Foo(); // assigning new instance to variable
foo.setBar(117);
}
这个改变在调用端是看不到的,因为方法内部的 foo
变量已经被重新赋值。引用仅被按值传递,这些变量实际上并没有任何连接或关联,它们只是共享了一个值(即引用)。我们现在已经覆盖了方法内部一个变量拥有的引用,调用端的变量仍然拥有之前相同的引用。
Foo foo = new Foo();
foo.setBar(7);
doSomethingElseWithFoo(foo);
int bar = foo.getBar(); // still is 7!
这个有意义吗?
Anthony Pegram已经很好地解释了。
我想再补充一点。
你永远无法通过值传递对象。
在Java中,每个对象都是在堆中创建的。您有一个引用或者我们可以说是一个梯子来到达该对象。在函数调用的情况下,您将引用(按值)作为参数传递。因此,您在函数中有另一个指向相同对象的引用或梯子。您可以通过此引用访问该对象并对其进行更改。现在,如果您像Anthony那样更改了函数中的引用
foo = new Foo();
发生了什么,您刚在堆中创建了一个新对象,并且具有该对象的引用。在此步骤中,您将现有引用(对旧对象的引用)替换为新创建对象的引用。因此,在您的函数中,您失去了访问旧对象的方式。现在,如果您进行任何更改,则更改的是新创建的对象,而不是调用函数的对象。
谢谢。