csdn_export_md

2020-08-08 20:16:42

Arrays.copyOf和System.arraycopy學習心得

Array.copyOf使用方式

java.util.Arrays.copyOf(int[], int)

System.arraycopy使用方式

1java.lang.System.arraycopy(Object src, int srcPos,
 Object dest, int desPos, int length)

分析
Array.copyOf包含很多過載的方法,分爲基本型別和參照型別兩類過載, 首先從基本型別的過載看起, 我們選取典型的int型別的過載
A.基本型別過載

public static int[] copyOf(int[] original, int newLength) {
        int[] copy = new int[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

本質上是呼叫了System的arraycopy方法,這是一個native方法,用c語言實現,暫時知道用法就可以。
B.參照型別過載

@SuppressWarnings("unchecked")
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

點進去第三行的copyOf方法

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

其中

     * @param <U> 源陣列的類
     * @param <T> 返回的陣列的類
     * @param  original 需要複製的源陣列
     * @param newLength 新陣列的長度
     * @param newType 返回的陣列的型別
     * @return 返回指定長度的,源陣列的副本,newLength>original .length,則多餘的部分使用 nulls

第一步是:建立指定長度的某種型別的陣列。
(判斷要複製的目標陣列的型別是不是Object型別)

 T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);

第二步是:呼叫本地方法

System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));

關於深拷貝還是淺拷貝

這裏直接給出結論

1. 對於陣列元素是參照型別的,是淺拷貝.
2. 對於陣列元素是基本型別的, 是深拷貝.

其中System.arraycopy是最近底層的,使用的是記憶體複製,省去了大量的陣列定址存取等時間,故效率最高。