Java uses exactly one mode of passing arguments: pass-by-value.
同Python,Java也是以pass-by-value的方式传递参数,Java任何时候都是传值,原生类型和数据都一样。对象的位置称为“引用”,当传递对象的值时,实质上传递的是对象的引用。
public static void main(String[] args) {
Dog aDog = new Dog("Max");
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true, java passes by value
aDog.getName().equals("Fifi"); // false
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
上面的例子:aDog.getName()
返回“Max”
, main
里的aDog
的值没有变成Fifi
,因为对象的引用是通过值传递的,如果是通过引用传递的,那么main
里的aDog.getName()
在foo
函数调用后,将返回“Fifi”
。
同样:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
上面的例子,在调用foo(aDog)
后,狗的名字变成Fifi
,因为对象的名字在函数foo()
内部被设置。foo
在d
上执行的任何操作都是执行于aDog
自身。
传递对象作为实参的另一个例子:
public class Main{
public static void main(String[] args){
Foo f = new Foo("f"); //(1)
changeReference(f); // (3) It won't change the reference!
modifyReference(f); // It will modify the object that the reference variable "f" refers to!
}
public static void changeReference(Foo a){ // (2)
Foo b = new Foo("b"); // (4)
a = b; // (5)
}
public static void modifyReference(Foo c){ // (6)
c.setAttribute("c"); // (7)
}
}
逐步说明:
(1). 声明一个类型为Foo
, 名为f
的引用,并将它赋给一个类型为Foo
的具有属性"f"
的新的对象:
Foo f = new Foo("f");
(2). 声明一个类型为Foo
名为a
的引用,初始化为null
。
public static void changeReference(Foo a)
(3). 调用方法changeReference
时,引用a
将被赋给被传递进来用作实参的对象。
changeReference(f);
(4).声明一个类型为Foo
,名称为b
的引用,并将它赋给一个类型为Foo
并具有属性“b”
的新的对象。
Foo b = new Foo("b");
(5). a = b
重新将引用a
而不是f
赋给属性为“b”
的对象。
(6).当调用 modifyReference(Foo c)
方法时, 引用c
被创建,并被赋给属性为“f”
的对象。
(7).c.setAttribute("c");
将改变引用c
指向的对象的属性,此对象也是引用f
指向的对象。
开头的例子就能说明问题,这个新的例子没有多少新意。
[1]https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
[2]https://stackoverflow.com/questions/11102878/swapping-function-java-pass-by-value-code-failed