head first java里写到“java是通过值传递的,也就是通过拷贝传递”,由此得出结论,方法无法改变调用方传入的参数。该怎么理解呢?
看例子:
public class Test1 {
public static void main(String[] args) {
int x = 7;
System.out.println("传入方法之前:x="+x);
addOne(x);
System.out.println("传入方法之后:x="+x);
}
private static void addOne(int y){
y++;
System.out.println("传入参数被改变:y="+y);
}
}
输出:
传入方法之前:x=7
传入参数被改变:y=8
传入方法之后:x=7
因为方法改变的只是值的拷贝(变量y的值),所以对原值(变量x的值)不产生影响。所以x的值在被传入方法前后都为7.
那么在看下面的例子
public class Dog {
String name;
int age;
省略get,set
}
public class Test2 {
public static void main(String[] args) {
Dog yellow = new Dog();
yellow.setName("大黄");
System.out.println("传入方法之前:yellow的名字是"+yellow.getName());
changeName(yellow);
System.out.println("传入方法之后:yellow的名字是"+yellow.getName());
}
private static void changeName(Dog white){
white.setName("小白");
System.out.println("传入参数被改变:white的名字是"+white.getName());
}
}
传入方法之前:yellow的名字是大黄
传入参数被改变:white的名字是小白
传入方法之后:yellow的名字是小白
yellow的名字在被传入方法之前是“大黄”,传入方法之后却变成了“小白”,那么“方法无法改变调用方传入的参数”的说法是否仍然成立呢?
答案是肯定的。
Dog yellow与int i 的不同之处,int i 是primitive主数据类型变量,变量值就是7,所以拷贝给y的值是7,addOne方法执行前后x始终等于7。而前者是对象引用变量(yellow是获取Dog对象的位表示法,即所谓的指针),所以拷贝给Dog white的只是一个指针,yellow和white同时指向了堆内存中的同一个Dog对象。changeName方法改变了被指向的Dog对象的实例变量name的值,但是yellow指针始终指向这个Dog对象,被传入的值(指针)没有发生变化。