最近在学java,今天学到了数组这部分,发现一个问题,比较有趣(或者麻烦),拿出来说说。

java.lang.System的静态方法arraycopy()可以实现数组的复制,讲课的老师说这个方法效率比较高,如果数组有成千上万个元素,那么用这个方法,比用for语句循环快不少。于是我试了试,发现以下问题。

如果是复制一个一位数组,那么改变复制后的数组并不影响原数组。但是如果复制一个二维数组,那么改变其中任何一个数组,那么另一个的值也发生了变化。开始不是很明白,后来上网查了查资料,理解了其中奥妙。

java其实没有二维数组的概念,平常实现的二维数组只是元素是一维数组的一维数组,而数组也是引用类型,继承自Object类。数组是new出来的。这些性质也就导致arraycopy()二维数组时出现的问题。

如果是一维数组,那么元素都是基础类型(如int,double等),使用arraycopy()方法后,是把原数组的值传给了新数组,属于值传递。而如果是二维数组,数组的第一维装的是一个一维数组的引用,第二维里是元素数值。对二维数组应用arraycopy()方法后,第一维的引用被复制给新数组的第一维,也就是两个数组的第一维都指向相同的“那些数组”。而这时改变其中任何一个数组的元素的值,其实都修改了“那些数组”的元素的值,所以原数组和新数组的元素值都一样了。

OK,就是这样。

不明白可以看看这个例子:


public   class  TestArrayCopy {

/**
@param  args
*/
public   static   void  main(String[] args) {
//  TODO 自动生成方法存根

String[] s1 
=  { " 中国 " , " 山西 " , " 太原 " , " TYUT " , " zyy " , " 加拿大 " , " 不知道哪个州 " , " 不知道哪个市 " , " 不知道哪个学校 " , " yxf " };
String[] s2 
=   new  String[ 10 ];
System.arraycopy(s1, 
0 , s2,  0 10 );
s2[
6 =   " 假设蒙大拿州 " ;
s2[
7 =   " 假设蒙特利尔市 " ;
s2[
8 =   " 假设Montreal商学院 " ;

System.out.println(
" This is s1 " );
for ( int  i  =   0 ;i  <  s1.length ;i ++ ){
System.out.print(s1[i] 
+   " , " );
}

System.out.println(
" \nThis is s2 " );
for ( int  i  =   0 ;i  <  s2.length ;i ++ ){
System.out.print(s2[i] 
+   " , " );
}

String[][] s3 
=  {{ " 中国 " , " 山西 " , " 太原 " , " TYUT " , " zyy " },{ " 加拿大 " , " 不知道哪个州 " , " 不知道哪个市 " , " 不知道哪个学校 " , " yxf " }};
String[][] s4 
=   new  String[s3.length][s3[ 0 ].length];
System.arraycopy(s3, 
0 , s4,  0 , s3.length);

System.out.println(
" \nThis is original s3 " );
for ( int  i  =   0 ;i  <  s3.length ;i ++ ){
for ( int  j  =   0 ; j <  s3[ 0 ].length ;j ++ ){
System.out.print(s3[i][j] 
+   " , " );
}
}

s4[
1 ][ 1 =   " 假设蒙大拿州 " ;
s4[
1 ][ 2 =   " 假设蒙特利尔市 " ;
s4[
1 ][ 3 =   " 假设Montreal商学院 " ;

System.out.println(
" \nThis is s3 after s4 has changed. " );
for ( int  i  =   0 ;i  <  s3.length ;i ++ ){
for ( int  j  =   0 ; j <  s3[ 0 ].length ;j ++ ){
System.out.print(s3[i][j] 
+   " , " );
}
}

System.out.println(
" \nThis is s4 " );
for ( int  i  =   0 ;i  <  s4.length ;i ++ ){
for ( int  j  =   0 ; j  <  s4[ 0 ].length ; j ++ ){
System.out.print(s4[i][j] 
+   " , " );
}

}
}

}

结果:

This is s1
中国,山西,太原,TYUT,zyy,加拿大,不知道哪个州,不知道哪个市,不知道哪个学校,yxf,
This is s2
中国,山西,太原,TYUT,zyy,加拿大,假设蒙大拿州,假设蒙特利尔市,假设Montreal商学院,yxf,
This is original s3
中国,山西,太原,TYUT,zyy,加拿大,不知道哪个州,不知道哪个市,不知道哪个学校,yxf,
This is s3 after s4 has changed.
中国,山西,太原,TYUT,zyy,加拿大,假设蒙大拿州,假设蒙特利尔市,假设Montreal商学院,yxf,
This is s4
中国,山西,太原,TYUT,zyy,加拿大,假设蒙大拿州,假设蒙特利尔市,假设Montreal商学院,yxf,