Java中如何借助Super Type Tokens在运行时创建泛型数组
问题根源
Array.newInstance只接受原始类型的Class<?>对象作为入参,你当前的实现直接拿ParameterizedType实例传入,不符合方法要求- Java泛型数组在运行时的实际类型是擦除泛型参数后的原始类型数组,比如
LinkedListNode<Integer>[]运行时实际是LinkedListNode[],泛型参数只用于编译期类型校验
修复方案
首先修改TypeReference类,新增获取原始类型Class的方法,兼容普通Class和ParameterizedType两种场景:
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public abstract class TypeReference<T> { private final Type type; private final Class<T> rawType; public TypeReference() { Type superclass = getClass().getGenericSuperclass(); this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; // 提取原始类型Class if (this.type instanceof Class<?>) { this.rawType = (Class<T>) this.type; } else if (this.type instanceof ParameterizedType) { this.rawType = (Class<T>) ((ParameterizedType) this.type).getRawType(); } else { throw new IllegalArgumentException("不支持的类型: " + type); } } public Type getType() { return type; } public Class<T> getRawType() { return rawType; } }
然后修改generateRandomArray方法,直接使用提取好的原始类型生成数组:
import java.lang.reflect.Array; @SuppressWarnings("unchecked") public static <T> T[] generateRandomArray(int size, TypeReference<T> c) { return (T[]) Array.newInstance(c.getRawType(), size); }
注:这里的
(T[])强转会触发unchecked cast编译警告,因为运行时无法校验泛型参数,但我们已经保证原始类型匹配,该警告是安全的,上述代码已通过注解消除警告。
验证说明
修改后的代码运行时会生成LinkedListNode[]数组,编译期会自动做泛型类型校验,你可以直接将返回结果当作LinkedListNode<Integer>[]使用,不会出现类型转换错误。
内容的提问来源于stack exchange,提问作者Pasquale
相关产品推荐
相关产品推荐

