Java中的Arrays类的copyOf()方法
@SuppressWarnings("unchecked")
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
这个方法就是取出传入数组的class对象作为第三个参数,调用适用性更广的另一个函数而已.
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、参数说明
(1)、T代表传入的第三个个参数newType(传入的类型的class对象)
(2)、U代表传入的第一个对象original(即原数组的数据类型)
(3)、original - 要复制的数组
(4)、 newLength - 要返回的副本的长度
(5)、 newType - 要返回的副本的类型
2、三元运算符的判断条件 ((Object)newType == (Object)Object[].class)是用来判断newType是否是Object类型,在上述第一个方法的前提下代表判断原数组是否为Object类型的数组.(Object)newType这里为什么要转型是因为不转型会报错.因为使用去比较它们的内存地址,从而判断它们是不是同一类型,而使用==,就要向上强转为Object,不然编辑器不通过无法比较。
3、如果判断为真,即原数组是Object类型数组,则直接创建一个给定长度newLength的新的Object数组即可.(为什么要创建新数组呢?因为这个函数目的就是复制一个数组的指定部分到一个新数组.)
如果判断为假,即原数组不是Object类型数组,则调用(T[])Array.newInstance(newType.getComponentType(), newLength) 这个方法是新建一个数组,数组类型为newType中元素的类型(默认返回Object类型,可强制转换为正确类型,详情看下列代码示例),长度为指定的newLength.
Array.newInstance内部直接调用Array.newArray,newArray为本地方法,由虚拟机实现
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;
public class SystemArrayCopyTest {
public static void main(String[] args) {
Object o = Array.newInstance(String.class, 10);
System.out.println(o.getClass()); //class [Ljava.lang.String;
System.out.println(String.class); // class java.lang.String
}
}
可以看到,Array.newInstance的返回虽然是Object类型,但是它实质上是String数组,可以强制转换成String[],
如:String[] arr = (String[]) Array.newInstance(String.class, 10);
newType.getComponentType()
public native Class<?> getComponentType();
这个方法,返回数组内的元素类型,不是数组时,返回null
public class SystemArrayCopyTest {
public static void main(String[] args) {
String[] o = {"aa", "bb", "cc"};
System.out.println(o.getClass().getComponentType()); //class java.lang.String
System.out.println(Object.class.getComponentType());//null
}
}