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詳解java

1. 方法的含義
返回一個類型爲T的數組,數組的容量爲newLength和original.length中的小值,元素爲original數組中的元素(取0到newLength和original.length中的小值)數組

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

2. (Object)newType == (Object)Object[].class
判斷newType是不是Object數組函數

3. 爲何要加(Object)呢?
由於要用使用==去比較它們的內存地址,從而判斷它們是否是同一類型,而使用==,就要向上強轉爲Object,否則編輯器不讓經過,不能比較.net

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)後code

public class SystemArrayCopy {

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

4. newType.getComponentType()component

public native Class<?> getComponentType();

本地方法,返回數組內的元素類型,不是數組時,返回nullblog

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爲本地方法,由虛擬機實現get

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

6. (T[]) new Object[newLength],爲何Object[]能夠強制轉換成T[]呢?
判斷(Object)newType == (Object)Object[].class
爲true時,執行的是(T[]) new Object[newLength],那T就是Object,newType也是Object[].class,因此能夠強轉成T[]
爲false時,執行的是(T[]) Array.newInstance(newType.getComponentType(), newLength),Array.newInstance返回的本質就是T[],因此能夠強轉成T[]
7. 爲何強轉爲T[],而不是Object[]?
由於我這個方法就是要返回T[],這是方法編寫的本意

8. 做用
把源數組中元素的類型向上轉型
截斷數組,當給定長度小於給定數組時,就能夠實現截斷的效果

如:ArrayList底層數組的類型轉換使用的這個方法(ArrayList參數爲集合的構造函數中)

相關文章
相關標籤/搜索