Java中的克隆clone以及对数组的复制

一、浅克隆和深克隆

    1. 浅克隆(shadow clone)

    只需要复制对象的字段值,对于8种基本类型,如int,long,float等,则复制值;对于复合数据类型仅复制该字段值,如数组则复制地址,对于对象变量则复制对象的reference。

    2.深克隆(deep clone)

    深克隆和浅克隆的区别在于复合数据类型的复制。若对象中的某个字段为复合类型,在克隆对象的时候,需要为该字段重新创建对象。

二、Java数组的复制

1. 定义一个数组int[] a={3,1,4,2,5}; int[] b=a;  数组b只是对数组a的又一个引用,即浅拷贝。

  如果改变数组b中元素的值,其实是改变了数组a的元素的值,要实现深度复制,可以用clone或者System.arrayCopy

<span style="white-space:pre">	</span><pre name="code" class="java">int[] a={3,1,4,2,5};
int[] b=a.clone();
b[0]=10;
System.out.println(b[0]+"  "+a[0]);




但是clone和System.arrayCopy都是对一维数组的深度复制。

  2. 对于二维数组则不一样:

int[][] a={{3,1,4,2,5},{4,2}};
int[][] b=a.clone();
b[0][0]=10;
System.out.println(b[0][0]+"  "+a[0][0]);


输出为10。

10所以clone并不能直接作用于二维数组。

   因为java中没有二维数组的概念,只有数组的数组。所以二维数组a中存储的实际上是两个一维数组的引用。当调用clone函数时,是对这两个引用进行了复制。

  3. 要证明,只需看下面的输出

int[][] a={{3,1,4,2,5},{4,2}};
int[][] b=a.clone();
b[0][0]=10;
System.out.println(b[0][0]+"  "+a[0][0]);
System.out.println(a[0]==b[0]);


第5句输出为true.

用clone对二维数组进行复制,要在每一维上调用clone函数。

int[][] a={{3,1,4,2,5},{4,2}};
int[][] b=new int[a.length][];
for(int i=0;i<a.length;i++)
{ b[i]=a[i].clone();} 
b[0][0]=10;
System.out.println(b[0][0]+"  "+a[0][0]);
System.out.println(b[0]==a[0]);

输出为10  3 false

三、小结:

   数组的复制方法现在至少有四个思路:

   1. 使用循环结构 这种方法最灵活。唯一不足的地方可能就是代码较多

   2. 使用Object类的clone()方法, 这种方法最简单,得到原数组的一个副本。灵活形也最差。效率最差,尤其是在数组元素很大或者复制对象数组时。

   3. 使用Systems的arraycopy这种方法被告之速度最快,并且灵活性也较好,可以指定原数组名称、以及元素的开始位置、复制的元素的个数,目标数组名称、目标数组的位置。

   4. Arrarys类的copyOf()方法与copyOfRange()方法可实现对数组的复制

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章