关闭

掌握ReflectionUtils:解锁Java反射的无限可能

发表于:2024-1-15 10:04

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:一安    来源:一安未来

  前言
  反射是一种能够在运行时检查或操作程序结构、元数据和行为的特性。这使得程序能够动态地获取关于类、方法、字段等元素的信息,以及在运行时进行相应的操作。
  获取class对象的三种实现
  ·Class<? extends Demo> clazz = demo.getClass();
  · Class<Demo> clazz = Demo.class;
  · Class clazz = Class.forName("com.demo.Demo");
  而在Spring框架中,ReflectionUtils是org.springframework.util包下的一个实用工具类,旨在简化与反射相关的常见任务。它提供了一组方法,使得开发人员能够更方便地执行反射操作,而不必处理过多的样板代码。
  演示
  获取属性字段
  /**
   * 获取属性字段
   * 可以指定属性的类型:findField(Class<?> clazz, @Nullable String name, @Nullable Class<?> type)
  **/
  public static void findField(){
      //查找属性字段name
      Field name = ReflectionUtils.findField(Demo.class, "name");
      System.out.println(name);
  }
  获取对象的 field 属性值
  /**
  * 获取对象的 field 属性值
  **/
  public static void getField() {
      Demo demo = new Demo();
      demo.setName("一安未来");
      demo.setAge(20);
      //获取Demo中的name属性字段
      Field field = ReflectionUtils.findField(Demo.class, "name");
      //取消name属性的private权限控制
      ReflectionUtils.makeAccessible(field);
      //获取对象的姓名字段的值
      Object value = ReflectionUtils.getField(field, demo);
      System.out.println(value);
  }
  设置对象的 field 属性值
  /**
   * 设置对象的 field 属性值
   **/
  public static void setField() {
      Demo demo = new Demo();
      demo.setName("一安未来");
      demo.setAge(20);
      //获取Demo中的name属性字段
      Field field = ReflectionUtils.findField(Demo.class, "name");
      //取消name属性的private权限控制
      ReflectionUtils.makeAccessible(field);
      //设置对象的姓名字段的值
      ReflectionUtils.setField(field, demo, "一安未来_v2");
      System.out.println(demo.getName());
  }
  对象的值复制
  /**
  * 对象的值复制
  **/
  public static void shallowCopyFieldState() {
      Demo demo = new Demo();
      demo.setName("一安未来");
      demo.setAge(20);
      Demo demo1 = new Demo();
      //把对象demo的值复制到对象demo1上
      ReflectionUtils.shallowCopyFieldState(demo, demo1);
      System.out.println(demo1);
  }
  对给定类的所有方法执行一个操作
  /**
  * 对给定类的所有方法执行一个操作
  **/
  public static void doWithMethods(){
      ReflectionUtils.doWithMethods(Demo.class, method -> {
          // 处理每个方法
          System.out.println("找到方法:" + method.getName());
      });
  }
  对给定类的所有字段执行一个操作
  /**
  * 对给定类的所有字段执行一个操作
  **/
  public static void doWithFields(){
      ReflectionUtils.doWithFields(Demo.class, field -> {
          // 处理每个字段
          System.out.println("找到字段:" + field.getName());
      });
  }
  添加过滤器来选择性的处理方法或字段
  /**
  * 添加过滤器来选择性地处理方法或字段
  **/
  public static void doWithMethodsFilter(){
      ReflectionUtils.doWithMethods(
              Demo.class,
              method -> {
                  // 处理符合条件的方法
                  System.out.println("找到方法:" + method.getName());
              },
              method -> {
                  // 过滤器:选择性处理方法的条件
                  return method.getName().startsWith("get");
              }
      );
  }
  调用指定方法
  /**
   * 调用指定方法
   **/
  public static void invokeMethod() throws NoSuchMethodException {
      Demo demo = new Demo();
      // 获取方法对象
      Method method =demo.getClass().getDeclaredMethod("say", String.class);
      // 要传递的参数
      String [] methodArgs = { "一安未来" };
      ReflectionUtils.makeAccessible(method);
      ReflectionUtils.invokeMethod(method, demo, methodArgs);
  }
  测试
  public static void main(String[] args) throws NoSuchMethodException {
      findField();
      System.out.println("===============================");
      getField();
      System.out.println("===============================");
      setField();
      System.out.println("===============================");
      shallowCopyFieldState();
      System.out.println("===============================");
      doWithMethods();
      System.out.println("===============================");
      doWithFields();
      System.out.println("===============================");
      doWithMethodsFilter();
      System.out.println("===============================");
      invokeMethod();
  }
  输出:
  private java.lang.String org.yian.reflectionUtils.Demo.name
  ===============================
  一安未来
  ===============================
  一安未来_v2
  ===============================
  Demo(name=一安未来, age=20)
  ===============================
  找到方法:equals
  找到方法:toString
  找到方法:hashCode
  找到方法:getName
  找到方法:setName
  找到方法:say
  找到方法:getAge
  找到方法:setAge
  找到方法:canEqual
  找到方法:finalize
  找到方法:wait
  找到方法:wait
  找到方法:wait
  找到方法:equals
  找到方法:toString
  找到方法:hashCode
  找到方法:getClass
  找到方法:clone
  找到方法:notify
  找到方法:notifyAll
  找到方法:registerNatives
  ===============================
  找到字段:name
  找到字段:age
  ===============================
  找到方法:getName
  找到方法:getAge
  找到方法:getClass
  ===============================
  I'm 一安未来
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号