Java中无法直接new T[],因泛型擦除导致JVM运行时不知T类型;需用Array.newInstance(clazz, len)配合Class对象创建,返回Object需强转为T[],并传入具体类如String.class而非T.class。

Java 里不能写 new T[10],不是语法不让,而是 JVM 运行时根本不知道 T 是什么类型——泛型被擦除了。想安全造出真正 T[] 类型的数组,得靠 Array.newInstance() 配合显式的 Class 对象。
为什么必须传 Class,不能用 T.class?
因为 T.class 在编译后就不存在了,擦除后只剩 Object.class。JVM 创建数组需要确切的组件类型(比如 String[].class 的组件类型是 String.class),所以你得自己把类型信息“带进来”:
- 调用方明确传入
String.class、Integer.class等具体类对象 - 泛型方法签名里要声明
T[] method(Class clazz, int len) - 内部不能写
T.class,那会编译失败或得到错误的Object.class
标准写法与强制转换的处理
Array.newInstance() 返回的是 Object,不是 T[],所以必须强转。这个转换在编译期无法验证,但只要 clazz 和目标类型一致,运行时就是安全的:
- 加
@SuppressWarnings("unchecked")抑制警告(仅限该语句附近) - 不要把
String.class创建的数组转成Integer[],否则运行时报ClassCastException - 示例:
return (T[]) Array.newInstance(clazz, length);
基本类型和嵌套泛型的注意事项
这个方案对基本类型和泛型参数有天然限制:
- 支持
int.class、double.class等原始类型 Class,能创建int[];但不支持List,因为泛型擦除后它等价于.class List.class,丢失了String信息 - 想创建
List,只能退而求其次:用[] Object[],再手动转型,但失去编译期检查 - 多维数组可用
Array.newInstance(clazz, d1, d2),注意clazz是元素类型,不是数组类型(比如二维String数组,仍传String.class)
比起数组,优先考虑集合
泛型和数组本来就不兼容,硬用 Array.newInstance() 增加了调用负担和出错可能:
- 日常开发中,用
ArrayList或LinkedList更自然、更安全 - 只有对接老接口(如
toArray())、反射场景或性能敏感的底层工具类才值得上 - 若必须提供数组返回,可同时提供两个重载:一个接收
Class,另一个接收模板数组(类似list.toArray(new String[0])模式)











