Java集合转数组必须用toArray(T[])并传入类型匹配的空数组(如new String[0]),因toArray()返回Object[]强制转换会抛ClassCastException;泛型类中需调用方传模板数组或Class对象以绕过类型擦除。

Java中集合转数组的toArray方法,关键在于泛型参数的正确传递——必须使用带泛型的数组类型(如String[]),而非原始类型(如String.class)或不带泛型的Object[],否则会丢失类型信息或触发运行时异常。
为什么不能直接用 list.toArray()?
该方法返回Object[],无法直接赋值给具体类型数组(如String[]),强制转换会抛出ClassCastException。虽然编译通过,但运行时失败:
List<String> list = Arrays.asList("a", "b");
String[] arr = (String[]) list.toArray(); // 运行时报 ClassCastException
推荐写法:传入带泛型的空数组
调用toArray(T[])重载方法,传入一个**类型匹配、长度为0的数组**。JVM会根据该数组的运行时类型创建新数组并填充元素:
- 写法简洁安全,无需预估集合大小
- 数组类型在编译期和运行期都明确,无类型擦除风险
- 即使传入长度非零的数组,只要足够容纳元素,也会复用;不足则新建
List<String> list = Arrays.asList("a", "b");
String[] arr = list.toArray(new String[0]); // 推荐:长度为0更高效
为什么不建议传 new String[list.size()]?
虽能工作,但存在冗余开销:
- 需提前获取
size(),对某些集合(如LinkedList)是O(n)操作 - 若集合后续被修改,预分配长度可能不准确,导致数组复用失败
- 现代JVM对
new T[0]做了优化,性能与预分配基本持平
泛型类中如何安全传递数组类型?
当方法签名含泛型参数T时,不能直接写new T[0](因类型擦除)。应由调用方传入Class<T>或使用Array.newInstance:
<T> T[] convert(List<T> list, Class<T> clazz) {
@SuppressWarnings("unchecked")
T[] arr = (T[]) Array.newInstance(clazz, list.size());
return list.toArray(arr);
}
更优解是让调用方提供模板数组(保持类型安全):
<T> T[] toTypedArray(List<T> list, T[] template) {
return list.toArray(template);
}
// 调用:String[] r = toTypedArray(list, new String[0]);

















