这两个办法都是将列表List中的元素转导出为数组,不同的是,toArray()办法导出的是Object类型数组,而toArray[T[] a]办法导出的是指定类型的数组。

1. toArray()办法

toArray()办法会返回List中所有元素形成的数组,并且数组类型是Object[]。还要留神一点就是,toArray()返回的是一个新的数组对象,并且屡次执行toArray()办法取得的是不同的数组对象,并且对其中一个数组进行批改,不会影响到其余toArray()办法取得的数组,并且也不会影响到list自身原来存储的元素值.

private static class People{    String name;    public People(String name){        this.name = name;    }    @Override    public String toString() {        return "People{" +                "name='" + name + '\'' +                '}';    }}//People类和上一个例子中的一样,这里不再列出了。public static void main(String[] args) {    List<People> list = new ArrayList<>();    list.add(new People("小明"));    list.add(new People("小王"));    Object[] objects1 = list.toArray();    Object[] objects2 = list.toArray();    System.out.println("objects1 == objects2 : "+(objects1 == objects2));    ((People)objects1[1]).name = "小花";    System.out.println("show objects1: "+ Arrays.toString(objects1));    System.out.println("show objects2: "+ Arrays.toString(objects2));    System.out.println("show list: "+list);}

输入后果:

objects1 == objects2 : falseshow objects1: [People{name=‘小明’}, People{name=‘小花’}]show objects2: [People{name=‘小明’}, People{name=‘小花’}]show list: [People{name=‘小明’}, People{name=‘小花’}]

从这个例子的输入后果能够看出,对元素对象自身就行批改,会导致toArray()返回的所有数组中的内容都产生扭转,包含原始的list容器外面的元素类容。从这个例子能够得出,如果list.toArray()返回的数组中寄存的是list原始对象的援用,只是创立了一个新的数组来装这些援用,并没有对list中原始对象进行拷贝或复制。
ArrayList中toArray()的实现源码:

public Object[] toArray() {    return Arrays.copyOf(elementData, size);}

在ArrayList中的实现是调用了Arrays工具类的copyOf()办法,这和ArrayLIst类中元素的存储构造相干。至于Arrays.copyOf()办法的作用就是下面剖析的List的toArray()办法的作用了,因为toArray()实质上就是间接调用的Arrays.copyOf()办法了。

2、toArray[T[] a]办法

toArray(T[] a)办法应用了泛型参数,能够返回指定类型数组,然而这个泛型在确定的时候必须是list中元素类型的父类或自身,至于那个参数数组,其实就是为了传递参数类型罢了
底层源码:

@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {    if (a.length < size)        // Make a new array of a's runtime type, but my contents:        return (T[]) Arrays.copyOf(elementData, size, a.getClass());    System.arraycopy(elementData, 0, a, 0, size);    if (a.length > size)        a[size] = null;    return a;}

从实现源码中看出,首先会判断数组a的长度和list元素的个数,进行一个比拟,如果a数组的长度小于list元素个数,那么就会间接调用工具类Arrays.copyOf()办法间接进行一个拷贝,留神,这儿的是Arrays.copyOf(elementData, size, a.getClass())办法,是由元素类型参数的,就是最初一项参数,和toArray()办法实现Arrays.copyOf(elementData, size)不雷同。

接着在看,如果数组a的长度length不小于list元素个数,即a . l e n g t h > = s i z e a.length >= sizea.length>=size得话,就会走上面的流程,首先调用System.arraycopy(elementData, 0, a, 0, size)将ArrayList里的元素数组elementData中的元素拷贝到a对象中,至于这个System.arraycopy()在这里就不具体说了。

接下来会判断一下a.length 是否大于list元素个数size,如果大于的话,会在a[size]地位设置一个null,这个设置的目标是了toArray(T[] a)办法调用者从返回的数组中检测到null时就晓得前面曾经没有list元素对象了。

总结

List接口的toArray()办法就是间接调用Arrays.copyOf(elementData, size),将list中的元素对象的援用装在一个新的生成数组中。

List接口的toArray(T[] a)办法会返回指定类型(必须为list元素类型的父类或自身)的数组对象,如果a.length小于list元素个数就间接调用Arrays的copyOf()办法进行拷贝并且返回新数组对象,新数组中也是装的list元素对象的援用,否则先调用System.arraycopy()将list元素对象的援用装在a数组中,如果a数组还有残余的空间,则在a[size]搁置一个null,size就是list中元素的个数,这个null值能够使得toArray(T[] a)办法调用者能够判断null前面曾经没有list元素了。