ParameterizedType用于在运行时还原泛型实参,因Class仅表示原始类型而无法携带泛型信息;通过field.getGenericType()获取并判断instanceof ParameterizedType后,调用getActualTypeArguments()逐层解析嵌套泛型。

Java泛型在编译期会被擦除,运行时无法直接获取 List 中的 String ——但通过 Type 体系,尤其是 ParameterizedType,可以绕过类型擦除,还原真实泛型参数。
为什么需要ParameterizedType?
因为 Class 只能表示原始类型(如 ArrayList.class),无法携带泛型信息;而 ParameterizedType 是唯一能封装“带实际类型参数的泛型引用”的接口。比如:
-
Map→ 是ParameterizedType -
List extends Number>→ 不是ParameterizedType,而是WildcardType -
MyClass在类定义中出现的T→ 属于TypeVariable,不是ParameterizedType
如何从字段或方法签名中提取ParameterizedType?
核心路径是:获取 Field 或 Method 的 GenericType → 判断是否为 ParameterizedType → 调用其方法解析。
- 调用
field.getGenericType()或method.getGenericReturnType(),返回值是Type - 用
instanceof ParameterizedType安全判断 - 若成立,可调用:
getRawType():返回原始类型(如Class)
getActualTypeArguments():返回泛型实参数组(如[Class或嵌套的, Class ] ParameterizedType)
常见陷阱与应对
泛型信息必须在声明处“可见”,否则反射拿不到:
- 局部变量泛型(如
List)→ 无法获取,因未进入字节码签名list = new ArrayList(); - 匿名内部类可“固化”泛型:使用
new TypeToken,Gson 就是靠这个技巧保留类型- >() {}.getType()
- 父类泛型被子类继承时,需向上追溯:用
Class.getGenericSuperclass()获取父类的Type,再强转并解析
实战小例子:解析 List
假设字段声明为:private List
-
field.getGenericType()返回的是ParameterizedType -
getActualTypeArguments()[0]是另一个ParameterizedType(对应Map) - 对它再次调用
getActualTypeArguments(),就能拿到String和Object对应的Type实例(通常是Class)
不复杂但容易忽略:Type 体系不是用来“猜类型”的,而是按字节码里真实写下的泛型签名逐层解包。关键在源头声明是否规范、是否可被反射读取。










