关于Java中ArrayList类的toArray方法详解
先上源码:
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()是不安全的,如下所示:
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]也受影响了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)