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

开发 开发工具
在Spring框架中,ReflectionUtils是org.springframework.util包下的一个实用工具类,旨在简化与反射相关的常见任务。它提供了一组方法,使得开发人员能够更方便地执行反射操作,而不必处理过多的样板代码。

前言

反射是一种能够在运行时检查或操作程序结构、元数据和行为的特性。这使得程序能够动态地获取关于类、方法、字段等元素的信息,以及在运行时进行相应的操作。

获取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 一安未来

责任编辑:武晓燕 来源: 一安未来
相关推荐

2024-03-18 08:33:16

2023-09-27 22:53:04

图像处理是开源Java

2017-09-07 12:54:59

华为云计算HC大会

2022-07-19 14:04:39

数字化平台

2021-04-07 07:48:00

测试开发Java反射Spring

2015-05-21 08:53:21

华为HNC/华为

2021-01-24 07:42:35

前端Table组件技术热点

2021-07-14 08:31:08

Java反射机制Class类

2015-12-25 09:51:13

售前工程师圣诞成长

2023-10-27 14:25:26

组件库无限可能性

2012-09-21 10:04:03

宽带华为

2017-07-14 09:06:10

存储数据中心HCI

2018-07-31 10:04:22

京东云教育

2023-10-27 09:03:20

NginxWeb服务器

2021-03-08 07:23:33

Java IO 系统

2023-09-04 09:48:23

开发数据库

2018-11-08 10:10:17

2020-11-22 10:41:28

代码Google科技

2020-11-23 09:21:50

代码Google科技

2023-11-24 12:14:55

PythonVSCode
点赞
收藏

51CTO技术栈公众号