java.lang.System.arraycopy() 與java.util.Arrays.copyOf()的區別


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.NullPointerException
b = 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.ArrayStoreException

B 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);   //復制成功

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM