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

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

















