天天看點

Arrays.copyOf()方法詳解-jdk1.8

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;
}
           

可以看到,最終調用的是System.arraycopy()方法,關于這個方法使用,可檢視System.arraycopy詳解

1. 方法的含義

傳回一個類型為T的數組,數組的容量為newLength和original.length中的小值,元素為original數組中的元素(取0到newLength和original.length中的小值)

說白了,這個方法就是為了數組元素的向上轉型,還有就是截斷數組

2. (Object)newType == (Object)Object[].class

判斷newType是否是Object數組

3. 為什麼要加(Object)呢?

因為要用使用==去比較它們的記憶體位址,進而判斷它們是不是同一類型,而使用==,就要向上強轉為Object,不然編輯器不讓通過,不能比較

public class SystemArrayCopy {

    public static void main(String[] args) {
        System.out.println(Object.class == Integer.class);
    }
}
/*
編輯時報錯:
Error:(37, 41) java: 不可比較的類型: java.lang.Class<java.lang.Object>和java.lang.Class<java.lang.Integer>
*/
           

加上(Object)後

public class SystemArrayCopy {

    public static void main(String[] args) {
        System.out.println(Object.class == (Object)Integer.class);
    }
}
/*
false
*/
           

4. newType.getComponentType()

本地方法,傳回數組内的元素類型,不是數組時,傳回null

public class SystemArrayCopy {

    public static void main(String[] args) {
        String[] o = {"aa", "bb", "cc"};
        System.out.println(o.getClass().getComponentType());
        System.out.println(Object.class.getComponentType());
    }
}
/*
class java.lang.String
null
*/
           

5. Array.newInstance(newType.getComponentType(), newLength)

建立一個類型與newType一樣,長度為newLength的數組

public static Object newInstance(Class<?> componentType, int length)
    throws NegativeArraySizeException {
    return newArray(componentType, length);
}
private static native Object newArray(Class<?> componentType, int length)
        throws NegativeArraySizeException;
           
Array.newInstance内部直接調用Array.newArray,newArray為本地方法,由虛拟機實作

newInstance傳回為Object,實質為數組

public class SystemArrayCopy {

    public static void main(String[] args) {
        Object o = Array.newInstance(String.class, 10);
        System.out.println(o.getClass());
        System.out.println(String.class); // 用于對比
    }
}
/*
class [Ljava.lang.String;
class java.lang.String
*/
           
可以看到,Array.newInstance的傳回雖然是Object類型,但是它實質上是String數組,可以強制轉換成String[],如:String[] arr = (String[]) Array.newInstance(String.class, 10);

4. (T[]) new Object[newLength],為什麼Object[]可以強制轉換成T[]呢?

  1. 判斷(Object)newType == (Object)Object[].class
  2. 為true時,執行的是(T[]) new Object[newLength],那T就是Object,newType也是Object[].class,是以可以強轉成T[]
  3. 為false時,執行的是(T[]) Array.newInstance(newType.getComponentType(), newLength),Array.newInstance傳回的本質就是T[],是以可以強轉成T[]

6. 為什麼強轉為T[],而不是Object[]?

因為我這個方法就是要傳回T[],這是方法編寫的本意

7. 作用

  1. 把源數組中元素的類型向上轉型
  2. 截斷數組,當給定長度小于給定數組時,就可以實作截斷的效果
如:ArrayList底層數組的類型轉換使用的這個方法(ArrayList參數為集合的構造函數中)