这个问题一直困扰着初级程序员,如果这个问题不能解决,以后在做程序的时候可能会收到影响。
其实这个问题是从C++中的传值和传指针中遗留来的,我们知道java中的引用其实是类似于C++中的指针,都是指向它所表示的对象,只不过java对指针有进行了一次封装,这样比直接拿到对象的指针操作起来更安全了,其实本质上都是指针。
对基本类型的变量,没有任何人去争论,都知道它是传值的。但是对于指针类型就迷糊了,因为在传递指针的时候,如果在函数中用指针对原来的对象进行了修改,这真的就会影响到它所指向的对象,也就是这么一个副作用,让我们觉得它不同于基本类型的值传递,也就有了引用传递一说。
但是仔细研究一下,引用传递其实也是值传递,它传递的是引用的值,而不是引用指向的对象的值。传递的过程是这样进行的,当调用一个方法并向方法传递一个引用参数是,会先把原来的引用复制一份然后传递给这个方法,你没有看错,这就像基本类型传递一样,先将基本类型的值复制一份然后传递给方法,那么我们在方法中对这个引用值做的任何修改都不会对原来这个引用的原版造成任何影响。我们可以用下面这个交换两个引用值的方法来说明这一点。
public class Test{
public static void main(String[] args){
People xiaoming = new People(21, "xiaoming");
People dazhang= new People(34, "dazhang");
System.out.println("交换前====================");
System.out.println(xiaoming);
System.out.println(dazhang);
swap(xiaoming, xiaozhang);
System.out.println("交换后====================");
System.out.println(xiaoming);
System.out.println(dazhang);
}
public static void swap(People a, People b){
People temp;
temp =a; a = b; b = temp;
}
class People{
int age;
String name;
public People(int age, String name){
this.age = age; this name = name;
}
public String toString(){
return name + ":" + age;
}
}
}
如果我们对传进来的引用副本指向的对象做了修改,那引用原版指向的对象相应的也发生了改变,这也可以通过下面一个程序来验证。
public class Test{
public static void main(String[] args){
People xiaoming = new People(21, "xiaoming");
System.out.println("Before change==================");
System.out.println(xiaoming.name + ":" + xiaoming.age);
change(a);
System.out.println("After change==================");
System.out.println(xiaoming.name + ":" + xiaoming.age);
}
public static void changeAge(People a){
a.age = 108;
}
class Peopel{
int age;
int name;
public People(int age, int name){
this.age = age; this.name = name;
}
}
}