ArrayList LinkedList源码解析(2)

从上面的源码中我们看到,先将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();
    }
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a28bd8cda7fd42444934c8d7ef084553.html