System.arraycopy()方法及对象的深复制和浅复制

1、System.arraycopy方法实现数组的复制

1-1:System中提供了一个native静态方法arraycopy(),可以使用这个方法实现数组之间的复制。对于普通的一维数组来说,会复制每个数组的值到另一个数组中,即每个元素都是按值传递,修改副本不会影响原来的值。方法原型及复制复制基本类型数组的示例如下:

/**

* System.arraycopy的方法原型

* @param src      要复制的源数组

* @param srcPos    源数组要复制的起始位置(从0开始)

* @param dest      要复制的目标数组

* @param destPos  目标数组的起始位置(从0开始)

* @param length    要复制的长度

*/publicstaticnativevoidarraycopy(Object src,intsrcPos,Object dest,intdestPos,intlength);

publicstaticvoidmain(String[]args){int[]nums={1024,1025,1026,1027,1028};int[]copyOfNums=newint[nums.length];System.arraycopy(nums,0,copyOfNums,0,nums.length);//修改拷贝数组的元素copyOfNums[3]=1234;//观察原数组有无变化System.out.println(Arrays.toString(nums));}

输出结果:[1024, 1025, 1026, 1027, 1028]

因为复制普通数组时,按值传递,会把每个元素的值复制一份给新数组,所以修改副本不会影响原来的值。

字符串数组就比较特殊了,先看代码:

String[]names={"王昭君","赵飞燕","陈圆圆","杨玉环","苏妲己"};System.out.println("原数组中每个元素的哈希码:");for(String name:names){System.out.print(Integer.toHexString(name.hashCode())+", ");}String[]copyOfNames=newString[names.length];System.arraycopy(names,0,copyOfNames,0,names.length);copyOfNames[1]="洛神甄氏";System.out.println("\n复制数组中每个元素的哈希码,1号元素的哈希码已经发生了改变:");for(String name:copyOfNames){System.out.print(Integer.toHexString(name.hashCode())+", ");}System.out.println();//修改copyOfNames中元素后的原数组内容没有改变System.out.println(Arrays.toString(names));

运行后的结果如下:

原数组中每个元素的哈希码:

1be7059, 225f8ec, 23f0508, 1929eae, 1f6458e,

复制数组中每个元素的哈希码,1号元素的哈希码已经发生了改变:

1be7059, 336eea6e, 23f0508, 1929eae, 1f6458e,

[王昭君, 赵飞燕, 陈圆圆, 杨玉环, 苏妲己]

内存图如下:

1-2:复制对象数组

//实体类publicclassBeauty{privateString name;privateintlevel;privatedoubleface;publicBeauty(){}publicBeauty(String name,intlevel,doubleface){this.setName(name);this.setLevel(level);this.setFace(face);}@OverridepublicStringtoString(){returnname+", "+level+", "+face;}//省略 getters/setters}

//测试方法publicclassArraycopyDemo{publicstaticvoidmain(String[]args){Beauty[]beauties=newBeauty[5];beauties[0]=newBeauty("王昭君",5,86.25);beauties[1]=newBeauty("赵飞燕",6,76.25);beauties[2]=newBeauty("陈圆圆",7,56.25);beauties[3]=newBeauty("杨玉环",8,66.25);beauties[4]=newBeauty("苏妲己",9,96.25);Beauty[]newBeauties=newBeauty[beauties.length];System.arraycopy(beauties,0,newBeauties,0,beauties.length);//修改复制后数组元素的属性newBeauties[1].setName("洛神甄氏");//打印原数组中的内容,观察1号元素的name属性,已经被修改了for(Beauty beauty:beauties){System.out.println(beauty);}}}

运行结果:

内存原理如下:

得出的结论:

1、当数组为一维数组,且元素为基本类型或String类型时,属于深复制,即原数组与新数组的元素不会相互影响

2、当数组为多维数组,或一维数组中的元素为引用类型时,属于浅复制,原数组与新数组的元素引用指向同一个对象

这里说的影响,是两个数组复制后对应的元素,并不一定是下标对应

String的特殊是因为它的不可变性

多维数组实际上可以理解为一维数组中的每个元素又是一个一维或多维数组的首地址,所以复制时的效果与对象数组的结果是一样的

老九学堂出品,转载请私信哦

对于文章内容有不理解的可以添加老九君个人QQ:614940318,请备注来自

老九学堂免费C、C++、Java课程地址:

https://study.163.com/courses-search?keyword=%E8%80%81%E4%B9%9D%E5%AD%A6%E5%A0%82

你可能感兴趣的:(System.arraycopy()方法及对象的深复制和浅复制)