標籤:
java.lang.System.arraycopy() 與java.util.Arrays.copyOf()的區別
一、java.lang.System.arraycopy()
該方法的聲明:
/* @param src 源數組 * @param srcPos 源數組中的起始位置 * @param dest 目標數組 * @param destPos 目標數組中的起始位置 * @param length 需要被複製的元素個數 * @exception IndexOutOfBoundsException 如果在複製的過程中發生索引溢界異常 * @exception ArrayStoreException 如果源數組中的元素因為類型不符不能被複製到目標數組中 * @exception NullPointerException 如果源數組為null或者目標數組為null */ public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); //由修飾符native可知,該方法調用的為JDK中的底層函數
該方法實現的功能為:從指定源數組中指定的位置開始,依次將元素複製到目標數組的指定位置,複製的元素個數為length參數。即,
將數組src[srcPos, ..., srcPos+length-1]中的元素複製到數組dest[destPos, ..., destPos+length-1]中。
如果源數組(src)和目標數組(dest)為相同的數組對象,則複製過程為:
① 將源數組中需複製的元素src[srcPos, ..., srcPos+length-1]複製到一個臨時數組中,長度為length;
② 然後將臨時數組中的內容複寫到目標數組dest[destPos, ..., destPos+length-1]中。
二、java.util.Arrays.copyOf()
該方法的聲明:
/* @param <T> 數組中元素的類型 * @param original 被複製數組 * @param newLength 返回的數組的長度 * @return 返回源數組的一個“副本”,為了去達到指定的長度,必要情況下需截斷或用null值填充 * @throws NegativeArraySizeException 如果參數newLength為負值 * @throws NullPointerException 如果參數original為null * @since 1.6 */ @SuppressWarnings("unchecked") public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); } /* @param <U> 源數組中元素的類型 * @param <T> 返回數組中元素的類型 * @param original 被複製數組 * @param newLength 返回的數組的長度 * @param newType 返回數組的類型 * @return 返回源數組的一個“副本”,為了去達到指定的長度,必要情況下需截斷或用null值填充 * @throws NegativeArraySizeException 如果參數newLength為負值 * @throws NullPointerException 如果參數original為null * @throws ArrayStoreException 如果源數組中的元素不能被複製到類型為newType的數組中 * @since 1.6 */ 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] //(返回數組)的類型為Object[]時 : (T[]) Array.newInstance(newType.getComponentType(), newLength); //用newType的組件類型,長度newLength去建立一個新的數組 System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); //截斷或用null值填充 return copy; }
//java.util.Arrays重載了很多copyOf()方法 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; }
該方法實現的功能為:按指定的長度複製給定的源數組,必要情況下需截斷或用null值填充。
Arrays.copyOf()的實現方式是:
① 內部建立一個長度為指定長度參數newLength的數組copy[];
② 調用System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength))完成對數組複製的功能
if(original.length >= newLength) 截斷original[];original[0, ..., newLength-1] -> copy[0, ..., newLength-1]
if(original.length < newLength) 用null值填充;original[0, ..., original.length-1] -> copy[0, ..., original.length-1]
nulls -> copy[original.length, ..., newLength-original.length+1]
③ 返回一個長度為newLength的數組copy[],元素為②中得到的對應值
三、異同
1) Arrays.copyOf()內部是通過System.arraycopy()實現的。
2) System.arraycopy()通過對srcPos,destPos的設定完成對數組的任意部分複製功能;而Arrays.copyOf()只能從下標為0的元素開始複製。
3)System.arraycopy()中會因為srcPos+length > src.length 或 destPos+length > dest.length而報ArrayIndexOutOfBoundsException;而Arrays.copyOf()中不會因此而報錯,因為Arrays.copyOf()返回的為方法內部建立的一個指定長度的數組。
String[] a = {"a","b","c","d","e"};String[] b = new String[4];//System.arraycopy(a, 0, b, 0, 5); //java.lang.ArrayIndexOutOfBoundsException//b = Arrays.copyOf(a, 4); //截斷a[],b={"a","b","c","d"}b = Arrays.copyOf(a, 5); //b={"a","b","c","d","e"}//b = Arrays.copyOf(a, 6); //null值填充,b={"a","b","c","d","e",null}
4) 在System.arraycopy()方法中,如果目標數組dest==null,則會報NullPointerException;而Arrays.copyOf()中不會因此而報錯。
String[] a = {"a","b","c","d","e"};String[] b = null;//System.arraycopy(a, 0, b, 0, 5); //java.lang.NullPointerExceptionb = Arrays.copyOf(a, 5); //b={"a","b","c","d","e"}
5)System.arraycopy()方法中目標數組作為參數;而Arrays.copyOf()中目標數組作為傳回值。
6) System.arraycopy()方法和Arrays.copyOf()方法均可以實現數群組類型的向上轉換,即子類型的數組可以複製到父類型數組中;但不可以實現向下轉換,即父類型的數組不可以複製到子類型數組中。
class A {}class B extends A{}A a1 = new A();A[] parent = {a1,a1,a1,a1,a1};B[] child = new B[5];//child = (B[]) Arrays.copyOf(parent, 5); //java.lang.ClassCastException//System.arraycopy(parent, 0, child, 0, 5); //java.lang.ArrayStoreExceptionB b1 = new B();B[] child = {b1,b1,b1,b1,b1};A[] parent = new A[5];//parent = Arrays.copyOf(child,5); //複製成功//System.arraycopy(child, 0, parent, 0, 5); //複製成功
java.lang.System.arraycopy() 與java.util.Arrays.copyOf()的區別