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參數爲集合的構造函數中)