在List类的具体实现类 ArrayList类中,有一个toArray()方法,该方法的作用是将ArrayList类型的对象转换为数组。
该类型有两个方法:1.toArray() 和 2. toArray(T[])
先来看一下源码:
public Object[] toArray() { return Arrays.copyOf(this.elementData, this.size); }
首先,返回值变成了Object[]类型,而toArray()的实质是调用了Arrays.copyof()方法。
由于是用的idea的反编译,所以,参数类型显示的是var变量值,但是,这个不影响我们阅读简单的代码。
public static <T> T[] copyOf(T[] var0, int var1) { return (Object[])copyOf(var0, var1, var0.getClass()); }
到这个我们发现了,这么一行代码:public static <T, U> T[] copyOf(U[] var0, int var1, Class<? extends T[]> var2) { Object[] var3 = var2 == Object[].class?(Object[])(new Object[var1]):(Object[])((Object[])Array.newInstance(var2.getComponentType(), var1)); System.arraycopy(var0, 0, var3, 0, Math.min(var0.length, var1)); return var3; }
这就是ArrayList.toArray()方法的实质。Object[] var3 = var2 == Object[].class?(Object[])(new Object[var1]):(Object[])((Object[])Array.newInstance(var2.getComponentType(), var1));
如果我们ArrayList容器中元素的类型是Object[]类型,那么就new一个Object的数组,然后调用把ArrayList对象中的元素依次复制进入新的数组,然后新数组。System.arraycopy
下面看一下ArrayList(T[]var1)这个方法,其实这才是关键
我们看到了,其内部实现,是将ArryList列表的长度和我们提供的数组var1的长度进行比较,如果:public <T> T[] toArray(T[] var1) { if(var1.length < this.size) { return (Object[])Arrays.copyOf(this.elementData, this.size, var1.getClass()); } else { System.arraycopy(this.elementData, 0, var1, 0, this.size); if(var1.length > this.size) { var1[this.size] = null; } return var1; } }
1.ArrayList列表长度更长,那么就调用Arrays.copyOf()方法,和上面一样,生成新的数组,然后依次将元素复制过去。
2.如果var1数组的长度更长,那就好办了,直接使用var1数组进行一个元素复制的操作,那么,var1数组更长的部分怎么办呢?
仅仅是将ListArray对象长度的末尾置为了null,然后后面的就不管了。
var1[this.size] = null;
我们可以写一个例子测试一下toArray(T[]var1)方法:
String[]var1 = new String[3]; var1[0] ="0"; var1[1] = "1"; var1[2] = "2"; System.out.println("var1 的地址 :" + var1); List<String> ll= new ArrayList<String>(); ll.add("zzz"); System.out.println("复制后的地址 :" + ll.toArray(var1)); for(String i : var1){ System.out.println(i);
我们的var1[]数组长度为3,而定义的ArrayList列表st长度为1.现在将st列表复制进入var数组,我们预计的结果是,复制后的地址和原来var1的地址是一样的,并且var1中第一个元素被换成了"zzz",第二个元素变成了null,第三个元素不变下面看一下结果:var1 的地址 :[Ljava.lang.String;@74a14482 复制后的地址 :[Ljava.lang.String;@74a14482 zzz null 2
发现结果果然如此。