从上面的源码中我们看到,先将c.toArray()方法的返回值赋值给elementData,将elementData.length赋值给size, 然后进行了一个判断 if(elementData.getClass() != Object[].class),若为真,则调用Arrays.copyOf()方法创建一个新Object[]数组,将原来elementData中的元素copy到新建的Object[]数组中,最后将新建的数组赋值给elementData。
我们看一下Arrays.copyOf()方法的源码:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
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;
}
如果newType类型为Object[].class的话,则直接创建一个长度为newLength的Object数组,否则使用Array.newInstance(Class<?> componentType, int length)方法创建一个元素类型为newType.getComponentType() (该方法返回数组中元素的类型)类型的,长度为newLength的数组,这是一个native方法,然后使用System.arraycopy() 这个native方法将original数组中的元素copy到新创建的数组中,并返回该数组。
我们注意 c.toArray might (incorrectly) not return Object[],按理说一个c.toArray()返回的是一个Object[]类型,其getClass()返回的也一定是Object[].class,那为什么还要进行逐个判断呢? 可真实情况真的是这样吗?我们看下面的示例:
//定义一个父类Animal
public class Aniaml {
}
//定义Animal的子类Person
public class Person extends Aniaml{
private int id;
private String name;
private Date birthday;
public Person(int id, String name, Date birthday) {
this.id = id;
this.name = name;
this.birthday = birthday;
}
public static void main(String[] args) {
test1();
test2();
test3();
}
public static void test1(){
Person[] persons = {new Person(100,"lewis",new Date()),new Person(100,"lewis",new Date())};
//class [Lcom.lewis.guava.Person; Person的数组类型
System.out.println(persons.getClass());
Aniaml[] aniamls = persons;
//class [Lcom.lewis.guava.Person; Person的数组类型
System.out.println(aniamls.getClass());
//class com.lewis.guava.Person Person类型
System.out.println(aniamls[0].getClass());
//java.lang.ArrayStoreException animals[]数组中实际存储的是Peron类型,当运行时放入非Person类型时会报错ArrayStoreException
aniamls[0] = new Aniaml();
}
public static void test2(){
List<String> list = Arrays.asList("abc");
//class java.util.Arrays$ArrayList 由此可见该类型不是ArrayList类型
System.out.println(list.getClass());
Object[] objects = list.toArray();
//class [Ljava.lang.String; 返回的是String数组类型
System.out.println(objects.getClass());
//java.lang.ArrayStoreException: java.lang.Object 当我们将一个Object放入String数组时报错ArrayStoreException
objects[0] = new Object();
}
public static void test3(){
List<String> dataList = new ArrayList<String>();
dataList.add("");
dataList.add("hehe");
//class java.util.ArrayList
System.out.println(dataList.getClass());
Object[] objects1 = dataList.toArray();
//class [Ljava.lang.Object;
System.out.println(objects1.getClass());
objects1[0]="adf";
objects1[0]=123;
objects1[0]=new Object();
}
}