You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从泛型类中获取类型变量与字段的映射关系?

获取泛型类字段与类型变量的映射关系

要解决泛型擦除导致无法直接获取字段关联类型变量的问题,核心是利用Java反射API读取字段的泛型类型签名,而非擦除后的原始类型。以下是具体实现方式,同时结合Jackson反序列化泛型的原理说明:

1. 直接获取字段与类型变量的映射

不要使用Field.getType()(返回擦除后的类型),改用Field.getGenericType()保留编译时的泛型信息,直接提取字段关联的类型变量:

import java.lang.reflect.Field;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.Map;

class RowClass<T1, T2> {
    public T1 t1;
    public T2 t2;
    public T1 t3;
}

public class GenericFieldMapping {
    public static void main(String[] args) {
        Map<String, String> fieldTypeVarMap = new HashMap<>();

        for (Field field : RowClass.class.getDeclaredFields()) {
            Type<?> genericType = field.getGenericType();
            if (genericType instanceof TypeVariable) {
                TypeVariable<?> typeVar = (TypeVariable<?>) genericType;
                fieldTypeVarMap.put(field.getName(), typeVar.getName());
            }
        }

        // 输出映射关系
        fieldTypeVarMap.forEach((field, typeVar) -> System.out.println(field + " -> " + typeVar));
    }
}

运行结果:

t1 -> T1
t2 -> T2
t3 -> T1

2. 结合子类实际类型参数,获取字段的实际类型

如果有子类指定了泛型的实际类型(比如你定义的RowClassImpl),可以先建立类型变量与实际类型的映射,再关联到对应字段:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.Map;

class RowClass<T1, T2> {
    public T1 t1;
    public T2 t2;
    public T1 t3;
}

class RowClassImpl extends RowClass<String, Integer> {}

public class GenericFieldActualType {
    public static void main(String[] args) {
        // 1. 建立类型变量与实际类型的映射
        ParameterizedType superType = (ParameterizedType) RowClassImpl.class.getGenericSuperclass();
        Type[] actualTypes = superType.getActualTypeArguments();
        TypeVariable<?>[] typeVars = RowClass.class.getTypeParameters();
        
        Map<TypeVariable<?>, Type> typeVarToActualType = new HashMap<>();
        for (int i = 0; i < typeVars.length; i++) {
            typeVarToActualType.put(typeVars[i], actualTypes[i]);
        }

        // 2. 遍历字段,获取实际类型
        for (Field field : RowClass.class.getDeclaredFields()) {
            Type genericType = field.getGenericType();
            if (genericType instanceof TypeVariable) {
                Type actualType = typeVarToActualType.get(genericType);
                System.out.println(field.getName() + " -> " + actualType.getTypeName());
            }
        }
    }
}

运行结果:

t1 -> java.lang.String
t2 -> java.lang.Integer
t3 -> java.lang.String

3. Jackson反序列化泛型的核心原理

Jackson处理List<String>这类泛型时,逻辑和上述实现一致:

  • 当你使用new TypeReference<List<String>>() {}时,Jackson通过反射读取这个匿名内部类的父类(TypeReference)的参数化类型,拿到完整的泛型信息。
  • 内部会构建类型变量到实际类型的映射表,反序列化时根据该映射解析JSON数据,避免泛型擦除导致的类型丢失。

内容的提问来源于stack exchange,提问作者Machi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:42:46