1.Arrays类是一个 final 类,其类中含有一个私有的 ArrayList, ArrayList的定义与 java.util.ArrayList中的定义相同。
java源码:
- public class ArrayList<E> extends AbstractList<E>
- implements List<E>, RandomAccess, Cloneable, java.io.Serializable
- {
2. Arrays调用 toArray()时, 调用的是 ArrayList 中数据数组的 clone, 当调用 toArray(T[])时,则使用 System.arraycopy()。
Arrays.java
- <span style="font-size:18px;"> <span style="white-space:pre"> </span>@Override
- public Object[] toArray() {
- return a.clone();
- }
- @Override
- @SuppressWarnings("unchecked")
- public <T> T[] toArray(T[] a) {
- int size = size();
- if (a.length < size)
- return Arrays.copyOf(this.a, size,
- (Class<? extends T[]>) a.getClass());
- System.arraycopy(this.a, 0, a, 0, size);
- if (a.length > size)
- a[size] = null;
- return a;
- }</span>
3. ArrayList 则是调用 Arrays.copyof, 再调用Arrays类中的 System.arraycopp。
ArrayList.java
- <pre name="code" class="java">public Object[] toArray() {
- return Arrays.copyOf(elementData, size);
Arrays.java
- <span style="font-size:18px;"> public static <T> T[] copyOf(T[] original, int newLength) {
- return (T[]) copyOf(original, newLength, original.getClass());
- }</span>
4. 分析一下运行结果。
- <span style="font-size:18px;"><span style="white-space:pre"> </span>@Test
- public void test() {
- // 使用 Arrays类中 toArray
- StringBuilder sb = new StringBuilder("a");
- Object[] o = new Object[] {sb, "b", "c"};
- Arrays.asList(o).toArray();
- System.out.println(sb.toString());
- sb.setCharAt(0, 'X');
- System.out.println(sb.toString());
- // 使用 ArrayList 类中的 toArray
- StringBuilder sb2 = new StringBuilder("a");
- Object[] o3 = new Object[] {sb2, "b", "c"};
- new ArrayList<>(Arrays.asList(o3)).toArray();
- System.out.println(sb2.toString());
- sb.setCharAt(0, 'X');
- System.out.println(sb2.toString());
- }</span>
5.结果:a X a a
6. 使用 T 方法时,两个结果都是一样的,因为都是使用 System.arraycopy 方法,而不是使用 clone() 方法。
ArrayList.java
- <span style="font-size:18px;">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;
- }
- </span>
Arrays.java
- <span style="font-size:18px;"> public <T> T[] toArray(T[] a) {
- int size = size();
- if (a.length < size)
- return Arrays.copyOf(this.a, size,
- (Class<? extends T[]>) a.getClass());
- System.arraycopy(this.a, 0, a, 0, size);
- if (a.length > size)
- a[size] = null;
- return a;
- }</span>
7. 总结
推荐使用带有参数的
toArray(T[] a)
方法,这样就避免了浅克隆带来的问题。