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

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

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

public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> 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<? extends T[]> newType  ,新数组的类型

“ Class<? extends T[]> ” 这里使用递归泛型,目的是使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<? extends Object[]>) aClass == Object[].class;

System.out.println(flag1);//false
System.out.println(flag2);//true
System.out.println(flag3);//false
System.out.println((Class<? extends Object[]>) aClass.getComponentType());//null
}