copyOfRange方法--源码分析

首先看看Arrays.copyOfRange泛型方法:

public static  T[] copyOfRange(T[] original, int from, int to) {
        return copyOfRange(original, from, to, (Class) original.getClass());
    }

里面实际调用的是更加通用的泛型方法copyOfRange(),那么继续往下看

public static  T[] copyOfRange(U[] original, int from, int to, Class newType) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        @SuppressWarnings("unchecked")                         //所有类都是Object类的子类
        T[] copy = ((Object)newType == (Object)Object[].class) //将newType强转为Object才能通过编译,进行比较
            ? (T[]) new Object[newLength]  
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));//防止了to大于原数组长度的情况
        return copy;
    }

分析输入的参数:

U[] original ,原数组(可传入任意类型数组)

int from ,原数组的要复制的起始位置

int to ,原数组的要复制的终点位置

Class newType  ,新数组的类型

“ Class ” 这里使用递归泛型,目的是使newType保证一定是数组类型

(对递归泛型的概念不清楚的朋友可以看看我写过的一篇文章)​​建造者模式-具有递归类型参数的泛型类型(Effective-Java) ​​

重点:源码中的一个判断条件:(Object)newType == (Object)Object[].class

1.如果newType是Object[]类型的,那么直接使要返回的copy数组为new出的Object[newLength]

2.如果不等,而Java中我们是无法直接new出T[](泛型数组)的,因此通过反射去获取。数组特有的getComponentType()方法,可得到数组元素的类型

过程中,出现的 数组类型数组元素类型 是两种class对象

public static void main(String[] args) throws ClassNotFoundException {
        
        Class aClass = Class.forName("java.lang.Object");
        
        boolean flag1 = aClass == Object[].class;
        boolean flag2 = aClass == Object[].class.getComponentType();
        boolean flag3 = (Class) aClass == Object[].class;
    
        System.out.println(flag1);//false
        System.out.println(flag2);//true
        System.out.println(flag3);//false
        System.out.println((Class) aClass.getComponentType());//null
    }

你可能感兴趣的:(Java,java,开发语言)