当前位置: 首页 > news >正文

通过反射,提取 Cat 类 泛型 父类 接口 属性 的具体类型参数

 1.父类

  1. 用 Cat.class 拿到 Class 对象,作为反射起点;
  2. 调用 getGenericSuperclass() 拿到带泛型信息的父类类型;
  3. 判断并转换为 ParameterizedType ,再用 getActualTypeArguments() 提取泛型参数,最终可通过 getTypeName() 等方法查看参数具体类型

1. Class<Cat> catClass = Cat.class;

  • 作用:获取 Cat 类的 Class 对象,这是反射的基础入口。通过 Class 对象,能动态获取类的结构(比如父类、接口、方法等),后续对泛型父类的操作都基于它展开。

2. Type genericSuperclass = catClass.getGenericSuperclass();

  • 作用:获取 Cat 类带有泛型信息的直接父类类型 。
    • 如果父类是泛型类(比如 class Cat extends Animal<String> ),它能保留泛型参数(如 String );
    • 若父类没使用泛型,返回结果和 getSuperclass() 类似(但类型是 Class )。
  • 对比
    •   getSuperclass() 只能获取父类的 Class 对象,丢失泛型参数 。比如父类是 ArrayList<String> ,用它拿到的是 ArrayList.class ,看不到 <String> ;]
    •   getGenericSuperclass() 能拿到包含 <String> 的完整泛型父类信息 。

3. ParameterizedType 相关逻辑

  • 判断与转换

    j

    if(genericSuperclass instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
    }
    
    • 先通过 instanceof 判断父类类型是否是参数化类型(即带泛型的类型,如 ArrayList<String> 、自定义泛型父类 Animal<String> ) 。\
    • 强转
    • 转换后,就能通过 ParameterizedType 的 API 提取泛型参数。

 

  • getActualTypeArguments()

     

    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    

     


    作用是获取泛型父类的实际类型参数 。
    •         比如父类是 Animal<String> ,调用后返回 Type 数组,里面存着 String.class 对应的 Type 信息;
    •         若父类是 Map<String, Integer> ,则返回 [String, Integer] 对应的 Type 数组。

 

 

2.接口

// 1. 获取 Mouse 类的 Class 对象,反射的入口
Class<Mouse> mouseClass = Mouse.class;  // 2. 获取 Mouse 类实现的所有接口的“泛型类型信息” 
Type[] genericInterfaces = mouseClass.getGenericInterfaces();  // 3. 遍历每个接口的类型信息
for (Type g : genericInterfaces) {  // 4. 判断接口是否是“参数化类型”(即带泛型的接口,比如 MyInterface<String>)if(g instanceof ParameterizedType){  // 5. 强转为 ParameterizedType,才能提取泛型参数ParameterizedType parameterizedType = (ParameterizedType) g;  // 6. 获取接口的实际泛型参数(比如 <String> 里的 String)Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();  // 7. 遍历泛型参数,输出类型名称for(Type a : actualTypeArguments){  System.out.println(a.getTypeName());  }}
}

 

  • getGenericInterfaces()
    作用是获取当前类实现的所有接口的 “泛型类型信息” 。
    • 和普通 getInterfaces() 区别:getInterfaces() 只能拿到接口的 Class 对象(丢失泛型参数);
    • getGenericInterfaces() 能保留泛型信息(比如 MyInterface<String> 完整保留)。

 

 

 

 

3.属性

public static void main(String[] args) throws Exception {// 1. 获取目标类的 Class 对象,作为反射入口Class<User> userClass = User.class;  // 2. 获取指定字段的 Field 对象(getDeclaredField 支持任意访问修饰符字段)Field mapField = userClass.getDeclaredField("map");  // (可选)若字段为非 public,解除访问限制mapField.setAccessible(true);  // 3. 获取字段带泛型信息的 Type 对象Type genericType = mapField.getGenericType();  // 4. 判断是否为参数化类型(带泛型的类型)if (genericType instanceof ParameterizedType) {  // 强转为 ParameterizedType,用于解析泛型参数ParameterizedType parameterizedType = (ParameterizedType) genericType;  // 5. 提取泛型的实际类型参数,返回 Type 数组Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();  // 6. 遍历泛型参数,获取并输出类型名称for (Type typeArg : actualTypeArguments) {  System.out.println(typeArg.getTypeName());  }}
}

 

 

  1. 获取 Class 对象:拿到目标类的反射入口,用于后续操作。
  2. 获取 Field 对象:通过getField/getDeclaredField定位具体成员变量。
  3. 获取泛型类型:用FieldgetGenericType拿到带泛型信息的Type对象。
  4. 判断并强转:检查Type是否为ParameterizedType,是则强转,为解析泛型做准备。
  5. 提取泛型参数:通过强转后的对象调用getActualTypeArguments,得到泛型参数数组。
  6. 遍历处理:循环泛型参数数组,用getTypeName获取并输出 具体类型名

 

 

4.获取方法参数上的泛型信息

 

 

 

 

 

总结

场景获取泛型类型的关键 API说明
字段泛型Field.getGenericType()针对单个字段的泛型解析
接口泛型Class.getGenericInterfaces()返回所有接口的泛型类型数组
父类泛型Class.getGenericSuperclass()返回直接父类的泛型类型
自身类泛型Class.getTypeParameters()TypeVariable[]类定义时声明的泛型变量(如 class MyClass<T> 中的 T

 

http://www.dtcms.com/a/277423.html

相关文章:

  • 【一起来学AI大模型】部署优化推理加速:TensorRT-LLM
  • 华为交换机 undo negotiation auto功能(华为交换机端口接光纤两端起不来)
  • Jvm优化高手-笔记
  • Cursor精准上下文指定
  • 印度纱丽变革:传统靛蓝工艺在无性别斗篷中的延续
  • TensorFlow深度学习实战(24)——变分自编码器详解与实现
  • 基于Springboot+UniApp+Ai实现模拟面试小工具三:后端项目基础框架搭建上
  • AI 助力:如何批量提取 Word 表格字段并导出至 Excel
  • React强大且灵活hooks库——ahooks入门实践之生命周期类hook(lifecycle)详解
  • vite---环境变量和模式配置(.env 文件)
  • 【论文阅读】Think Only When You Need with Large Hybrid-Reasoning Models
  • Linux进程状态实战指南:转换关系、监控命令与状态解析
  • 【Linux | 网络】应用层(HTTP)
  • html-input 系列
  • 二进制、八进制、十进制、十六进制的转换
  • 用 Node.js 构建模块化的 CLI 脚手架工具,从 GitHub 下载远程模板
  • HarmonyOS-ArkUI Web控件基础铺垫1-HTTP协议-数据包内容
  • 【基于开源大模型(如deepseek)开发应用及其发展趋势的一点思考】
  • 早期 CNN 的经典模型—卷积神经网络(LeNet)
  • 在Linux文件写入软件设计中,直接写入SSD时磁盘写入抖动(I/O延迟波动)的解决方案
  • [CH582M入门第六步]软件IIC驱动AHT10
  • Leetcode 3613. Minimize Maximum Component Cost
  • Vue文件上传实战指南
  • 深入理解 Linux 文件系统层级结构
  • Python 数据挖掘之数据探索
  • CCS-MSPM0G3507-7-模块篇-MPU6050的基本使用
  • Spring Boot 安全登录系统:前后端分离实现
  • MYSQL笔记1
  • 黑马点评系列问题之p63unlock.lua不知道怎么整
  • 嵌入式单片机开发 - Keil MDK 自定义 Output 与 Listing 输出