http://www.cnblogs.com/zhengbin/p/5671403.html
http://www.cnblogs.com/jjdcxy/p/5870524.html
Java數組拷貝主要有四種方法,分別是循環賦值,System.arraycopy(),Arrays.copyOf()(或者Arrays.copyOfRange)和clone()方法。下面分別介紹一下這幾種拷貝。
循環拷貝(速度相對比較慢)
循環拷貝其實沒什么好說的啦,就是用一個for循環進行元素的逐個拷貝,進行深拷貝或者淺復制這個大家可以自己把握。
System.arraycopy(淺拷貝)
這個是系統提供的拷貝方式,也是我們推薦使用的拷貝方式,它是淺拷貝,也就是說對於非基本類型而言,它拷貝的是對象的引用,而不是去新建一個新的對象。通過它的代碼我們可以看到,這個方法不是用java語言寫的,而是底層用c或者c++實現的,因而速度會比較快。
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
通過源代碼我們可以看到,關鍵字native說明它不是用java語言寫的,而是調用其他語言的代碼。
Arrays.copyOf(淺拷貝)
這個方法也是淺拷貝,為什么呢?我們看一下它的源代碼就知道了。
public static byte[] copyOfRange(byte[] original, int from, int to) { int newLength = to - from; if (newLength < 0) throw new IllegalArgumentException(from + " > " + to); byte[] copy = new byte[newLength]; System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength)); return copy; }
實際上它調用的就是System.arraycopy,所以肯定也是淺拷貝。
Object.clone
clone()比較特殊,對於對象而言,它是深拷貝,但是對於數組而言,它是淺拷貝。
對象拷貝
首先講一下對象的拷貝,它是深拷貝,大家可以用對象去測試一下。下面我們看一下它的源代碼:
protected native Object clone() throws CloneNotSupportedException;
這里也有native關鍵字,所以也是底層的C語言實現的。
還要注意的是,這里修飾符是protected,也就是說,我們創建了一個Object類以后,是不能直接調用這個clone()方法的,因為protected關鍵字只允許同一個包內的類和它的子類調用,所以我們聲明一個object類時,肯定不是同一個包內,所以就不能去調用它。
要調用這個方法,就需要我們寫一個類,然后聲明實現cloneable接口就好了,不需要去顯示地聲明繼承於object,因為java中的類如果不顯示說明父類的話,默認父類就是object。然后我們繼承這個方法:
@Override public Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); }
這里需要是,為了能夠在不同包內去調用這個方法,我們需要把這個權限升級為public。現在我們就可以調用這個類的clone()方法去拷貝我們的類了。
數組拷貝
對於數組而言,它不是簡單的將引用賦值為另外一個數組引用,而是創建一個新的數組。但是我們知道,對於數組本身而言,它它的元素是對象的時候,本來數組每個元素中保存的就是對象的引用,所以,拷貝過來的數組自然而言也是對象的引用,所以對於數組對象元素而言,它又是淺拷貝。我們用以下代碼驗證一下:
class Aby implements Cloneable{ public int i; public Aby(int i) { this.i = i; } @Override public Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } } public class Solution { public static void main(String[] args) throws CloneNotSupportedException { Aby aby1 = new Aby(1); Aby aby2 = (Aby) aby1.clone(); aby1.i = 2; System.out.println(aby1.i); //2 System.out.println(aby2.i); //1 Aby[] arr = {aby1,aby2}; Aby[] arr2 = arr.clone(); arr2[0].i = 3; System.out.println(arr[0].i); //3 System.out.println(arr2[0].i); //3 } }