toArray()最常用但不传参会抛ClassCastException;正确用法是传入泛型数组如new String[0];无法直接转基本类型数组,需用stream或手动遍历;Arrays.asList()返回列表不支持增删;并发集合toArray()返回快照。

用 toArray() 方法最常用,但不传参会出 ClassCastException
直接调用 list.toArray() 返回的是 Object[],哪怕你的集合是 ArrayList。如果后续强转成 String[],运行时就会抛 ClassCastException——这是新手踩得最多的一坑。
正确做法是传入一个带泛型类型的数组作为参数:
String[] arr = list.toArray(new String[0]);
注意三点:
-
new String[0]比new String[list.size()]更优:JVM 能根据实际长度重新分配,避免浪费或扩容 - 传
null会触发NullPointerException - 数组类型必须和集合元素类型兼容,否则编译不通过(如
list.toArray(new Integer[0])对List就报错)
泛型集合转基本类型数组不能靠 toArray()
toArray() 只能返回引用类型数组(Integer[]、String[]),无法直接得到 int[]、double[] 等基本类型数组。
立即学习“Java免费学习笔记(深入)”;
常见解决路径:
- 用 Java 8+ 的
stream()+mapToInt()等中间操作:int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
- 手动遍历填充(适合小数据量或对 GC 敏感场景)
- 第三方库如 Guava 的
Ints.toArray(),但会引入额外依赖
注意:stream().toArray() 默认返回 Object[],必须显式指定 mapToXxx 才能得到基本类型数组。
Arrays.asList() 返回的列表不能直接用 toArray() 转回原数组
Arrays.asList(array) 返回的是一个固定大小的内部列表实现(非 ArrayList),它底层仍持有原始数组的引用。此时调用 toArray() 看似正常,但若原数组是基本类型包装类(如 Integer[]),且你期望得到新数组副本,就容易误以为修改返回数组会影响原数组——其实不会,因为 toArray() 总是新建数组。
真正要小心的是:这个列表不支持 add()、remove(),一调就抛 UnsupportedOperationException。所以别把它当普通 ArrayList 用。
并发集合(如 CopyOnWriteArrayList)转数组是快照行为
调用 toArray() 时,这类集合会生成当前状态的完整副本,后续的写操作不影响已生成的数组。这在多线程读多写少场景下很安全,但也意味着:
- 数组内容可能“过期”,不是实时最新
- 大集合频繁调用会带来明显内存与 GC 压力
- 如果只读部分元素,不如用迭代器 + 条件判断,避免全量复制
没有银弹。选哪种方式,得看你是要一致性、性能,还是代码简洁性——而这些往往互相冲突。









