详解Java中的Arrays类的copyOf()方法

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

你可能感兴趣的:(Java基础)