泛型方法内部想写new T[size]会真实编译不过——这是系列前面反复验证过的泛型擦除的直接后果。这篇真实验证标准的绕过方式:java.lang.reflect.Array.newInstance(),以及它创建出来的数组到底是不是"真的"数组。
用Class对象在运行时决定要创建什么类型的数组——这正是泛型方法内部no法直接new T[size]时的标准解法。
ArrayReflectNewInstanceDemo.java static <T> T[] createArray(Class<T> componentType, int size) { return (T[]) Array.newInstance(componentType, size); // 泛型方法内部无法直接 new T[size] }
Array.newInstance(int.class, 5) 真实创建的类型: [I 真实设置intArray[0]=100后,读取: 100 真实创建的String[3]数组: [hello, null, null] 真实运行时类型: String[]
真实结果证明 Array.newInstance() 能在运行时才知道元素类型(通过 Class 对象)的情况下,动态创建出数组——这正是系列前面 泛型擦除那篇提到的限制的标准解决方案:泛型方法内部由于类型参数 T 在运行时已经被擦除,编译器不允许写 new T[size],但可以通过传入一个显式的 Class<T> 参数,用反射绕过这个限制。
反射创建的数组和普通数组真实是同一种运行时类型: true
真实创建的多维数组类型: [[I 真实多维数组维度: 2 x 3 反射数组越界访问真实抛出: ArrayIndexOutOfBoundsException Array.newInstance(-1) 真实抛出: NegativeArraySizeException
真实结果验证了 Array.newInstance() 还有一个重载版本,能一次性传入维度数组直接创建多维数组;而涉及数组安全性的异常行为(越界访问、负数长度)真实和普通数组语法完全一致——反射这条路径完整复用了 JVM 底层数组机制的所有真实检查逻辑,没有走任何"捷径"绕过这些安全保障。
每一行都是真实运行这段代码得到的结果。