一、淺克隆和深克隆
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()方法可實現對數組的複製