前言
在程序设计语言中,方法的参数传递大致有两种类型:按值传递和按引用传递。按值传递表示,方法用一个形参来接收实际传入的参数,在函数内对形参做操作;而按引用传递是指方法接收的是变量地址,可以修改对应的变量值。在Java核心技术卷1里,告诉我们,Java总是采用按值传递。
传递基本数据类型
public static void add(int temp){
temp = 2*temp;
}
public static void main(String[] args){
int num = 3;
System.out.println("调用前num的值:"+num);
add(num);
System.out.println("调用后num的值:"+num);
}
如上代码,当参数是int等基本数据类型时,由于java是按值传递参数,形参temp的值被初始化为3,temp = temp*2;只是将形参temp的值翻倍,并没有影响到实参num的值。
传递对象引用类型
Java除了基本数据类型外,还有对象引用类型,核心技术卷1告诉我们,在Java中,任何对象变量的值都是存储在另一个地方的对象的引用。比方说String s = new String("test");代码中new String("test")是构造了一个String类型的对象,内容为"test",并且它的值是对新创建对象的引用,s即是存储了这个对象的引用。
class Person{
private int age;
public Person(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class someInterface {
public static void add(Person per){
per.setAge(per.getAge()+1);
}
public static void main(String[] args){
Person p = new Person(18);
System.out.println("调用前age为:"+p.getAge());
add(p);
System.out.println("调用后age为:"+p.getAge());
}
}
如上代码,运行之后发现成功的将age加了1,这是由于Java按值传递将p的值也就是新建的Person对象的引用给形参per,相当于per和p都是该对象的引用(一个对象可以有多个引用),指向了同一个对象,per对对象做出了修改,再用p查看该对象内容,自然可以得到想要的效果。
那么有人说了,这是不是说明Java在传递基本数据类型时是按值传递,而在传递对象类型时是按引用传递呢?其实不是,同样是那个类,看如下代码:
public class someInterface {
public static void swap(Person per1,Person per2){
System.out.println("per1:"+per1+" per2:"+per2);
Person temp = per1;
per1 = per2;
per2 = temp;
System.out.println("per1:"+per1+" per2:"+per2);
}
public static void main(String[] args){
Person p1 = new Person(18);
Person p2 = new Person(20);
System.out.println("调用前p1:"+p1+" p2:"+p2);
swap(p1,p2);
System.out.println("调用后p1:"+p1+" p2:"+p2);
}
}
可以看出,调用swap前后,p1和p2指向的对象并没有变,如果传的是引用,那是可以交换成功的。并且通过跟踪打印swap函数中的值可以发现,只是把形参per1和per2的值进行了交换,这证明了Java在传递对象引用类型参数时也是按值传递。