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[]呢?
- 判斷(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[]
6. 為什麼強轉為T[],而不是Object[]?
因為我這個方法就是要傳回T[],這是方法編寫的本意
7. 作用
- 把源數組中元素的類型向上轉型
- 截斷數組,當給定長度小于給定數組時,就可以實作截斷的效果
如:ArrayList底層數組的類型轉換使用的這個方法(ArrayList參數為集合的構造函數中)