在Java中,将基本数据数据类型或对象传递给一个方法,我们通常会说一个是值传递,一个是引用传递,但是真的是这样吗?
其实这种说法是错误的,在Java中,所有都是严格的值传递。
疑问
假设有下面一串代码,两个类Foo和Dog,在Foo类的方法中,操作Dog类
class Foo {
public static void main(String[] args) {
Dog a = new Dog();
a.setName("狗1号");
System.out.println(a.getName());
new Foo().setDog(a);
System.out.println(a.getName());
}
public void setDog(Dog b) {
b = new Dog();
b.setName("狗2号");
}
}
class Dog {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
上面代码的执行结果为:
狗1号
狗1号
如果按照引用传递的说法来解释,在Foo类中的setDog方法传递的Dog dog是引用,那为什么更改了引用,改为狗2号
,在main方法第二次打印的却还是狗1号
呢?
解释
Dog dog = new Dog();
dog.setName("狗1号");
当代码执行到这里时,我们初始化了一只名字叫做狗1号
的Dog对象。

new Foo().setDog(a);
当代码执行调用方法时,问题就在这里,这里将a变量传入到方法setDog,发生的是值传递还是引用传递呢?
这里是值传递,这个值,指的是引用值(指针或者内存值)。
变量a是个引用,有个引用值,指向存在内存里的对象,这样才能正确的操作狗1号
对象。
执行setDog方法时,Java将变量a的引用值,复制一份给了变量b(值传递给了变量b),所以变量b也可以操作狗1号
对象。

public void setDog(Dog b) {
b = new Dog();
b.setName("狗2号");
}
代码继续执行,执行方法块里的代码,注意此时有一个b = new Dog();
的操作,此操作会将变量b的引用值改变,也就是说此时变量b和a指向的不再内存里同一个Dog对象。

到这里也就能说明问题了,Java中是不存在引用传递的,因为如果变量b是引用传递,那b改变了引用指向的对象,那变量a也应该改变执行的对象,这样才是引用传递。而如果变量b是值传递,就可以解释,为什么在setDog()方法执行过后,变量a还是指向原来的对象。
我上面解释的可能也不是很清晰明了,大家可以看下面的网址,讲的更清楚。