首先看看 Arrays.copyOfRange 泛型方法: public static T T [] copyOfRange ( T [] original , int from , int to ) { return copyOfRange ( original , from , to , ( Class ? extends T [] ) original . getClass ()); } 里面实际调用的是
首先看看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
}