今天写程序时遇到一个十分诡异的bug。在debug了很久之后,总是发现自己的算法整个过程是没有任何问题的,但是结果却一直不对,后来发现错误后,以为是自己对于拷贝的理解有误导致的。我开始认为对二维数组是进行的浅拷贝,导致出了问题。因此,我王大锤写了程序来测试我的想法,事实证明,这并不是浅拷贝或者深拷贝的问题,而在于对引用的理解。
public class Test {
public static void main(String[] args) {
double a[]=new double[4];
set(a);
for(int i=0;i<a.length;i++)
System.out.print(a[i]+" ");
}
public static void set(double []after){
double []origin=new double[]{1,2,3,4};
after=origin.clone();
}
}
look,上面的程序中,打印出的是什么?会是1,2,3,4吗?如果你是这样想的话,too simple,too naive!如上所示,我的after是作为函数参数来使用的,在origin数组clone之后得到,并不是使得after本身的数组元素改变了,而是使after这个引用指向了origin的数组,在函数内部打印的话,的确你会得到1,2,3,4,但是,在函数返回时,所使用的栈空间被清空,after就原形毕露了。因此,使用clone来复制数组元素是一种比较愚蠢的做法,还不如使用Arrays.copy()或者System.arrayCopy()这些函数来的实在。
同理的,还有下面的程序是一样的道理:
public class A implements Cloneable {
int a=2;
int b=3;
public A(){}
public A(int a,int b){
this.a=a;
this.b=b;
}
public static void func(A a){
A b=new A(0,0);
try {
a=(A) b.clone();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]){
A t=new A();
func(t);
System.out.println(t.a+"--"+t.b);
}
}