ReflectUtils 反射工具类

一、工具类代码

继承hutool 包的 ReflectUtil 反射工具类,只要方法有:

  • 获取构造方法
  • 关于字段的操作(获取字段名称、 修饰符、 值)
  • 关于公共方法的操作
  • 实例化
  • 判断方法属性
  • 执行方法  
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ReflectUtils extends ReflectUtil {

    private static final String SETTER_PREFIX = "set";

    private static final String GETTER_PREFIX = "get";

    /**
     * 调用Getter方法.
     * 支持多级,如:对象名.对象名.方法
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeGetter(Object obj, String propertyName) {
        Object object = obj;
        for (String name : StringUtils.split(propertyName, ".")) {
            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
            object = invoke(object, getterMethodName);
        }
        return (E) object;
    }

    /**
     * 调用Setter方法, 仅匹配方法名。
     * 支持多级,如:对象名.对象名.方法
     */
    public static <E> void invokeSetter(Object obj, String propertyName, E value) {
        Object object = obj;
        String[] names = StringUtils.split(propertyName, ".");
        for (int i = 0; i < names.length; i++) {
            if (i < names.length - 1) {
                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
                object = invoke(object, getterMethodName);
            } else {
                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                Method method = getMethodByName(object.getClass(), setterMethodName);
                invoke(object, method, value);
            }
        }
    }

}

 二、测试反射获取属性、属性值等

package com.ruoyi.demo;

import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Filter;
import com.ruoyi.common.utils.reflect.ReflectUtils;

import java.lang.reflect.Field;

/**
 * <简述>
 * <详细描述>
 *
 * @author syf
 * @date 2024年08月19日 14:59
 */
public class TestReflectUtils {

    // Teacher类
    static class Teacher{
        private String name;
        private int age;
    }
    public static void main(String[] args) {
       testReflect();
    }


    //反射操作
    static  void testReflect(){
        // 获取Teacher类的所有字段
        Field[] fields = ReflectUtils.getFields(Teacher.class);
        for (Field field :fields) {
            Console.log("STAR---------------------------------------------------------------");
            Console.log("getFields-获取Teacher类的所有字段:", field);
            // 获取字段名
            Console.log("getFieldName->获取字段名:",ReflectUtils.getFieldName(field));
            // 获取字段值
            Console.log("getFieldValue->获取字段值:",ReflectUtils.getFieldValue(new Teacher(),field));
            // 获取字段修饰符
            Console.log("getModifiers->获取字段修饰符:",field.getModifiers());
            // 获取字段类型
            Console.log("getType->获取字段类型:",field.getType());
            Console.log("END---------------------------------------------------------------\n");
        }

        Console.log("STAR---------------------------------------------------------------");
        // 获取Teacher类的所有字段,返回age字段
        Field[] fields1 = ReflectUtils.getFields(Teacher.class, field -> "age".equals(field.getName()));
        for (Field field :fields1) {
            Console.log("getFields-返回age字段:", field);
        }
        Console.log("END---------------------------------------------------------------\n");

        //获取单个字段
        Field field = ReflectUtils.getField(Teacher.class, "age");
        Console.log("getField-获取单个字段:", field);
    }
}

打印结果:

STAR---------------------------------------------------------------
getFields-获取Teacher类的所有字段: private java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.name
getFieldName->获取字段名: name
getFieldValue->获取字段值: null
getModifiers->获取字段修饰符: 2
getType->获取字段类型: class java.lang.String
END---------------------------------------------------------------

STAR---------------------------------------------------------------
getFields-获取Teacher类的所有字段: private int com.ruoyi.demo.TestReflectUtils$Teacher.age
getFieldName->获取字段名: age
getFieldValue->获取字段值: 0
getModifiers->获取字段修饰符: 2
getType->获取字段类型: int
END---------------------------------------------------------------

getFields-返回age字段: private int com.ruoyi.demo.TestReflectUtils$Teacher.age
END---------------------------------------------------------------

getField-获取单个字段: private int com.ruoyi.demo.TestReflectUtils$Teacher.age

Process finished with exit code 0

三、反射进行GET、SET操作

public class TestReflectUtils {



    // Teacher类
    static class Teacher{
        private String name;
        private int age;

        private  static final String sex = "男";

        public void setName(String name) {
            this.name = name;
        }


    }
    public static void main(String[] args) {
       //testReflect();
        testFieldGet();
    }


    /**
     * <简述>get set 操作
     * <详细描述>
     * @author syf
     * @date 2024/8/19 16:32
     */

    static  void testFieldGet(){
        Field nameField = ReflectUtils.getField(Teacher.class, "name");
        Teacher teacher = new Teacher();
        teacher.setName("张三");
        // 方式1
        try {
            // 设置字段的可访问性,否则私有属性访问不到
            nameField.setAccessible(true);
            String s = (String) nameField.get(teacher);
            Console.log("get() = {}", s);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        //方式2
        String fieldValue = (String) ReflectUtils.getFieldValue(teacher, nameField);
        Console.log("getFieldValue->获取字段值:",fieldValue);
       //方式3
        String fieldValue1 = (String) ReflectUtils.getFieldValue(teacher, "name");
        Console.log("getFieldValue->获取字段值:",fieldValue1);


        //设置值
        ReflectUtils.setFieldValue(teacher, "name", "李四");
        Console.log("setFieldValue->设置字段值:",ReflectUtils.getFieldValue(teacher, "name"));
        ReflectUtils.setFieldValue(teacher, nameField, "王五");
        Console.log("setFieldValue->设置字段值:",ReflectUtils.getFieldValue(teacher, "name"));


        //获取final字段,修改value
        //初始化前先移除 final,否则修改不了
        ReflectUtils.removeFinalModify(ReflectUtils.getField(Teacher.class, "sex"));
        Teacher teacherFinalSex = new Teacher();
        ReflectUtils.setFieldValue(teacherFinalSex, "sex", "女");
        Console.log("setFieldValue->设置字段值:",ReflectUtils.getFieldValue(teacherFinalSex, "sex"));
    }

 GET、SET操作结果:

注意操作final 修饰的属性时候,要在实例化前移除 final属性

get() = 张三
getFieldValue->获取字段值: 张三
getFieldValue->获取字段值: 张三
setFieldValue->设置字段值: 李四
setFieldValue->设置字段值: 王五
setFieldValue->设置字段值: 女

四、反射获取构造方法

public class TestReflectUtils {


    // Teacher类
    static class Teacher{
        private String name;
        private int age;

        public Teacher() {
        }

        public Teacher(String name, int age) {
            this.name = name;
            this.age = age;
        }
        private  static final String sex = "男";

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
    }
    public static void main(String[] args) {
       //testReflect();
        // testFieldGet();
        testConstructor();
    }


    static void testConstructor(){
        // 获取所有构造方法
        Constructor<Teacher>[] constructors = ReflectUtils.getConstructors(Teacher.class);
        for (Constructor<Teacher> constructor : constructors){
            Console.log("getConstructors->获取构造方法:",constructor);
        }

        // 获取无参构造方法
        Constructor<Teacher> constructor = ReflectUtils.getConstructor(Teacher.class);
        Console.log("getConstructor->获取无参构造方法:",constructor);
        // 获取有参构造方法
        Constructor<Teacher> constructor1 = ReflectUtils.getConstructor(Teacher.class, String.class, int.class);
        Console.log("getConstructor->获取有参构造方法:",constructor1);

        String name = constructor1.getName();
        Console.log("name:{}",name);
        int modifiers = constructor1.getModifiers();
        Console.log("modifiers:{}",modifiers);

    }
}

打印测试结果:

获取无参构造,有参构造,修改成员变量属性

getConstructors->获取构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher()
getConstructors->获取构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher(java.lang.String,int)
getConstructor->获取无参构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher()
getConstructor->获取有参构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher(java.lang.String,int)
name:com.ruoyi.demo.TestReflectUtils$Teacher
modifiers:1

五、 反射获取实例化

重写object 的toString 方法,打印参数




    // Teacher类
    static class Teacher{
        private String name;
        private int age;

        public Teacher() {
        }

        public Teacher(String name, int age) {
            this.name = name;
            this.age = age;
        }
        private  static final String sex = "男";

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return StringUtils.format("Teacher{name={}, age={}}", this.name, this.age);
        }
    }
    public static void main(String[] args) {
       //testReflect();
        // testFieldGet();
        //testConstructor();
        testInstance();
    }

    /**
     * <简述>实例化
     * <详细描述>
     * @author syf
     * @date 2024/8/20 10:57
     */
    static void testInstance(){
        // 获取Teacher类的实例
        Teacher teacher = ReflectUtils.newInstance(Teacher.class);
        Console.log("newInstance->获取Teacher类的实例:",teacher);
        // 获取Teacher类的实例,传入参数
        Teacher teacher1 = ReflectUtils.newInstance(Teacher.class, "张三", 18);
        Console.log("newInstance->获取Teacher类的实例,传入参数:",teacher1);
    }

打印结果:

打印出实例化结果

newInstance->获取Teacher类的实例: Teacher{name=null, age=0}
newInstance->获取Teacher类的实例,传入参数: Teacher{name=张三, age=18}

 

六、反射获取成员方法

public class TestReflectUtils {

    // Teacher类
    static class Teacher{
        private String name;
        private int age;

        public Teacher() {
        }

        public Teacher(String name, int age) {
            this.name = name;
            this.age = age;
        }
        private  static final String sex = "男";

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return StringUtils.format("Teacher{name={}, age={}}", this.name, this.age);
        }
    }
    public static void main(String[] args) {
       //testReflect();
        // testFieldGet();
        //testConstructor();
        //testInstance();
        testMethod();
    }

    static void testMethod(){
        Method[] methods = ReflectUtils.getMethods(Teacher.class);
        for (Method method: methods) {
           if (method.getDeclaringClass().isInstance(Object.class)){
               Console.log("打印OBJECT的方法------------------------------------------------------------------------");
           }
            Console.log("getMethods->获取方法:",method);
        }
        Console.log("testMethod->获取方法:",ReflectUtils.getMethod(Teacher.class, "toString"));
    }
}

打印结果:

打印自带的成员方法

也会打印object自带的方法

getMethods->获取方法: public java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.toString()
getMethods->获取方法: public java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.getName()
getMethods->获取方法: public void com.ruoyi.demo.TestReflectUtils$Teacher.setName(java.lang.String)
getMethods->获取方法: public int com.ruoyi.demo.TestReflectUtils$Teacher.getAge()
打印OBJECT的方法-----------------------------
getMethods->获取方法: protected void java.lang.Object.finalize() throws java.lang.Throwable
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final void java.lang.Object.wait() throws java.lang.InterruptedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public boolean java.lang.Object.equals(java.lang.Object)
打印OBJECT的方法-----------------------------
getMethods->获取方法: public native int java.lang.Object.hashCode()
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native java.lang.Class java.lang.Object.getClass()
打印OBJECT的方法-----------------------------
getMethods->获取方法: protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native void java.lang.Object.notify()
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native void java.lang.Object.notifyAll()
打印OBJECT的方法-----------------------------
getMethods->获取方法: private static native void java.lang.Object.registerNatives()
testMethod->获取方法: public java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.toString()

 七、反射调用方法

public class TestReflectUtils {



    // Teacher类
    static class Teacher{
        private String name;
        private int age;

        public Teacher() {
        }

        public Teacher(String name, int age) {
            this.name = name;
            this.age = age;
        }
        private  static final String sex = "男";

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return StringUtils.format("Teacher{name={}, age={}}", this.name, this.age);
        }
    }
    public static void main(String[] args) {
       //testReflect();
        // testFieldGet();
        //testConstructor();
        //testInstance();
        //testMethod();
        testInvoke();
    }

   static void  testInvoke(){
        Teacher teacher = new Teacher();
        teacher.setName("张三");
        teacher.setAge(18);
        Console.log("invoke->反射调用方法:",ReflectUtils.invoke(teacher, "toString"));
   }

 执行结果:


调用了toString

invoke->执行toString结果: Teacher{name=张三, age=0}

 八、invokeSetter、invokeGetter

public static void main(String[] args) {
       //testReflect();
        // testFieldGet();
        //testConstructor();
        //testInstance();
        //testMethod();
        //testInvoke();

        testGetSet();

    }

    static void  testGetSet(){
        Teacher teacher = new Teacher();
        Console.log("name->invokeGetter方法执行:");
        ReflectUtils.invokeSetter(teacher, "name", "张三");

        String name =  ReflectUtils.invokeGetter(teacher, "name");
        Console.log("name->invokeGetter方法执行:",name);
    }

执行结果:

name->invokeGetter方法执行:
name->invokeGetter方法执行: 张三

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java 反射工具类 ReflectUtils 是一个提供了便捷的反射操作方法的工具类。它封装了 Java 反射 API 的一些常用功能,使得开发者能够更加方便地使用反射进行类、方法、字段的操作。 ReflectUtils 提供了以下几个方法: 1. getTypeArguments:通过反射获取指定类的泛型类型参数。可以通过该方法来获取泛型类型的具体参数类型,方便在运行时进行类型判断和操作。 2. invokeGetter:通过反射调用指定对象的指定字段的 getter 方法。在无法直接访问字段或需要动态调用字段的 getter 方法时,可以使用该方法。 3. invokeSetter:通过反射调用指定对象的指定字段的 setter 方法。在无法直接访问字段或需要动态调用字段的 setter 方法时,可以使用该方法。 4. getFieldValue:通过反射获取指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法获取字段的值。 5. setFieldValue:通过反射设置指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法设置字段的值。 6. getField:通过反射获取指定类的指定字段。可以用于获取字段的修饰符、类型等信息。 7. getMethod:通过反射获取指定类的指定方法。可以用于获取方法的修饰符、返回值类型、参数类型等信息。 ReflectUtils 的使用能够简化反射操作的代码,提高开发效率,但也需要注意合理使用,避免引入不必要的复杂性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syfjava

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值