全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-10 9 分钟 ✍️ juanwangdev

泛型与反射

类型擦除后运行时无泛型信息,但反射可获取部分泛型签名。

获取字段泛型类型

Java
public class MyClass {
    private List<String> stringList;
    private Map<String, Integer> map;
}

// 获取字段的泛型类型
Field field = MyClass.class.getDeclaredField("stringList");
Type genericType = field.getGenericType();

if (genericType instanceof ParameterizedType) {
    ParameterizedType pt = (ParameterizedType) genericType;
    Type rawType = pt.getRawType();           // List.class
    Type[] actualTypes = pt.getActualTypeArguments();
    System.out.println(actualTypes[0]);       // String.class
}

获取方法泛型类型

Java
public class MyClass {
    public List<String> getList() { return null; }
    public void setMap(Map<String, Integer> map) {}
}

// 获取返回类型泛型
Method method = MyClass.class.getMethod("getList");
Type returnType = method.getGenericReturnType();

if (returnType instanceof ParameterizedType) {
    ParameterizedType pt = (ParameterizedType) returnType;
    Type[] actualTypes = pt.getActualTypeArguments();
    System.out.println(actualTypes[0]);  // String.class
}

// 获取参数类型泛型
Method setMapMethod = MyClass.class.getMethod("setMap", Map.class);
Type[] paramTypes = setMapMethod.getGenericParameterTypes();
// paramTypes[0] 是 ParameterizedType

ParameterizedType 接口

Java
public interface ParameterizedType extends Type {
    Type[] getActualTypeArguments();  // 实际类型参数
    Type getRawType();                // 原始类型
    Type getOwnerType();              // 所属类型(嵌套时)
}
方法说明
getActualTypeArguments()获取泛型参数类型数组
getRawType()获取原始类型(如 List)
getOwnerType()获取外部类类型(嵌套类)

Type 接口体系

Java
Type(接口)
├── Class              // 普通类
├── ParameterizedType  // 参数化类型 List<String>
├── GenericArrayType  // 泛型数组 T[]
├── TypeVariable       // 类型变量 T
└── WildcardType       // 通配符 ?

获取继承的泛型信息

Java
public abstract class BaseDao<T> {
    private Class<T> entityClass;

    public BaseDao() {
        // 获取子类继承时指定的泛型类型
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) type;
            this.entityClass = (Class<T>) pt.getActualTypeArguments()[0];
        }
    }

    public Class<T> getEntityClass() {
        return entityClass;
    }
}

// 子类指定泛型类型
public class UserDao extends BaseDao<User> {}

// 使用
UserDao userDao = new UserDao();
Class<User> entityClass = userDao.getEntityClass();  // User.class

典型应用:框架中 DAO、Service 基类通过反射获取子类指定的泛型类型。

TypeToken(Gson)

Google Gson 使用 TypeToken 解决泛型擦除问题:

text
// 普通方式:无法获取 List<String> 类型
Type type = new TypeToken<List<String>>() {}.getType();

// 解析 JSON 为泛型集合
List<String> list = gson.fromJson(json, type);

TypeToken 通过匿名类保留泛型签名,反射获取。

泛型信息保留位置

位置保留泛型信息
类字段✅ Signature 属性
方法参数✅ Signature 属性
方法返回类型✅ Signature 属性
类继承✅ Signature 属性
运行时对象❌ 已擦除
局部变量❌ 不保留

Signature 属性:编译器在字节码中存储泛型签名,反射可读取。

要点总结

  • 泛型擦除后反射可通过 Signature 获取部分信息
  • getGenericType() 返回 Type(可能是 ParameterizedType)
  • ParameterizedType.getActualTypeArguments() 获取泛型参数
  • 字段、方法参数、返回类型、继承保留泛型签名
  • 运行时对象和局部变量不保留泛型信息
  • 典型应用:框架基类获取子类指定的泛型类型
  • TypeToken(Gson)通过匿名类保留泛型签名

📝 发现内容有误?点击此处直接编辑

← 上一篇 集合性能分析
下一篇 → 泛型与数组
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库