从 0 学 Java(22):反射获取类的泛型信息,解决泛型擦除问题
·
反射获取类的泛型信息(解决泛型擦除问题)
在Java中,泛型信息在编译后会被擦除(Type Erasure),导致运行时无法直接获取泛型的具体类型。但通过反射机制,我们可以从类、字段或方法的签名中获取保留的泛型元数据。以下是关键方法:
1. 获取父类泛型参数
当子类继承泛型父类时,可通过getGenericSuperclass()获取具体类型:
// 定义泛型父类
public abstract class BaseDao<T> {
private Class<T> entityClass;
public BaseDao() {
// 获取泛型T的实际类型
Type type = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) type;
this.entityClass = (Class<T>) pt.getActualTypeArguments()[0];
}
}
// 子类继承时指定具体类型
public class UserDao extends BaseDao<User> {}
// 测试
UserDao dao = new UserDao();
System.out.println(dao.getEntityClass()); // 输出: class User
2. 获取字段泛型类型
通过Field.getGenericType()解析字段的泛型签名:
public class Container {
private List<String> stringList;
}
// 获取字段泛型信息
Field field = Container.class.getDeclaredField("stringList");
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
Type actualType = pt.getActualTypeArguments()[0];
System.out.println(actualType); // 输出: class java.lang.String
}
3. 获取方法返回类型泛型
使用Method.getGenericReturnType()解析方法返回值:
public interface DataService {
List<Integer> getNumbers();
}
// 解析方法返回泛型
Method method = DataService.class.getMethod("getNumbers");
Type returnType = method.getGenericReturnType();
if (returnType instanceof ParameterizedType) {
Type actualType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
System.out.println(actualType); // 输出: class java.lang.Integer
}
4. 获取方法参数泛型
通过Method.getGenericParameterTypes()解析参数:
public class Processor {
public void process(Map<String, Object> config) {}
}
// 解析参数泛型
Method method = Processor.class.getMethod("process", Map.class);
Type[] paramTypes = method.getGenericParameterTypes();
ParameterizedType mapType = (ParameterizedType) paramTypes[0];
Type[] mapArgs = mapType.getActualTypeArguments();
System.out.println(Arrays.toString(mapArgs));
// 输出: [class java.lang.String, class java.lang.Object]
关键点总结
| 场景 | 反射方法 | 返回类型 |
|---|---|---|
| 父类泛型参数 | getClass().getGenericSuperclass() |
ParameterizedType |
| 字段泛型类型 | Field.getGenericType() |
Type |
| 方法返回类型泛型 | Method.getGenericReturnType() |
Type |
| 方法参数泛型 | Method.getGenericParameterTypes() |
Type[] |
注意:泛型信息仅存在于显式声明的位置(如父类、字段、方法签名)。匿名内部类或未指定具体类型的变量无法获取泛型信息。
通过合理使用这些反射API,可在运行时突破泛型擦除限制,实现动态类型处理,适用于ORM框架、序列化工具等需要类型元数据的场景。
更多推荐


所有评论(0)