先上源码:
public Object[] toArray() { return Arrays.copyOf(elementData, size); }
可以看到ArrayList类的toArray()方法调用了Arrays.copyOf(elementData,size)(其中的elementData是ArrayList类中用来存储对象的数组,size是数组大小),接下来进入其内部:
public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); }
发现它又调用了重载的copyOf(original, newLength, original.getClass())方法,继续深入:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") 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; }
原来它会先创建一个T数组引用copy,之后调用System.arraycopy进行复制(对于普通类型的original数组,System.arraycopy是深复制,否则,是浅复制)。至此,可以下定结论,toArray()方法每次放回的数组引用不同,对于普通类型的ArrayList实例来说,toArray是安全的,但是对于对象类型的ArrayList实例来说,toArray是不安全的,如下所示:
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static java.lang.reflect.Proxy.newProxyInstance; public class A implements Cloneable{ public String name; public static void main(String[] args) throws CloneNotSupportedException { ArrayList<A> objects = new ArrayList<>(); A a1 = new A(); a1.name = "1"; objects.add(a1); A[] objects1 = (A[])objects.toArray(new A[0]); A[] objects2 = (A[])objects.toArray(new A[0]); objects1[0].name = "2"; System.out.println(objects1[0].name); System.out.println(objects2[0].name); } }
可以看到只修改了objects1[0],但objects2[0]也受影响了。
标签:toArray,Java,newLength,ArrayList,original,copyOf,public From: https://www.cnblogs.com/rockdow/p/17503389.html