Java 反射实战:动态属性处理的艺术 - 图表参数解析器揭秘 ...

十念  论坛元老 | 2024-12-15 22:55:14 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1030|帖子 1030|积分 3090

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
场景还原:为什么需要反射?

想象如许一个场景:我们正在开发一个数据可视化系统。系统需要根据用户的差别查询需求,动态地从图表参数对象中提取特定属性。
传统方法的局限性
传统的硬编码方式会导致:
代码重复
扩展性差
每增长一个属性就要修改代码
题目的具体场景

  1. // 图表参数对象
  2. public class ChartsParam {
  3.     private List<String> categories;     // 类别列表
  4.     private List<Integer> values;        // 数值列表
  5.     private String title;                // 图表标题
  6.     private boolean isMultiSeries;       // 是否多序列
  7. }
  8. // 统计过滤器
  9. public class StatisticsFilter {
  10.     private String property;  // 要查找的属性名
  11. }
复制代码
我们的目标是:根据 StatisticsFilter 中指定的 property,从 ChartsParam 中动态获取对应的属性值。下面是反射的具体实现:
  1. public List<StatisticsResult> processChartParameters(
  2.     List<StatisticsFilter> panelParams,
  3.     ChartsParam chartsParam
  4. ) {
  5.     List<StatisticsResult> results = new ArrayList<>();
  6.     for (StatisticsFilter panelParam : panelParams) {
  7.         String property = panelParam.getProperty();
  8.         
  9.         try {
  10.             // 关键步骤1:获取字段
  11.             Field field = chartsParam.getClass().getDeclaredField(property);
  12.             
  13.             // 关键步骤2:设置可访问
  14.             field.setAccessible(true);
  15.             
  16.             // 关键步骤3:获取字段值
  17.             Object value = field.get(chartsParam);
  18.             
  19.             // 关键步骤4:根据不同类型处理
  20.             if (value != null) {
  21.                 StatisticsResult result = new StatisticsResult();
  22.                 result.setProperty(property);
  23.                 result.setValue(value);
  24.                 results.add(result);
  25.             }
  26.             
  27.         } catch (NoSuchFieldException | IllegalAccessException e) {
  28.             // 优雅地处理异常
  29.             log.warn("属性 {} 不存在或无法访问", property, e);
  30.         }
  31.     }
  32.     return results;
  33. }
复制代码
深入解析反射的每个步骤


  • 获取字段 getDeclaredField()
    作用:根据属性名动态获取对应的 Field 对象
    特点:可以获取私有字段,不受访问修饰符限制
  • 设置可访问 setAccessible(true)
    作用:突破 Java 的访问权限控制
    意义:允许访问私有、受保护的字段
  • 获取字段值 field.get()
    作用:从对象中获取指定字段的现实值
    机动性:可以获取恣意类型的字段值
利用示例:
  1. public void demonstrateReflectionUsage() {
  2.     // 构造图表参数
  3.     ChartsParam chartsParam = new ChartsParam();
  4.     chartsParam.setCategories(Arrays.asList("北京", "上海", "广州"));
  5.     chartsParam.setValues(Arrays.asList(100, 200, 150));
  6.     chartsParam.setTitle("城市销售对比");
  7.     chartsParam.setMultiSeries(true);
  8.     // 定义要获取的属性
  9.     List<StatisticsFilter> panelParams = Arrays.asList(
  10.         new StatisticsFilter("categories"),
  11.         new StatisticsFilter("values")
  12.     );
  13.     // 调用反射处理方法
  14.     List<StatisticsResult> results = processChartParameters(panelParams, chartsParam);
  15.     // 输出结果
  16.     results.forEach(result ->
  17.         System.out.println(result.getProperty() + ": " + result.getValue())
  18.     );
  19. }
复制代码
优点
动态性:运行时决定要处理的属性
机动性:可以处理未知的属性
扩展性:添加新属性无需修改核心代码
局限性
性能开销较大
失去编译期类型检查
大概粉碎封装性

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

十念

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表