玩转 ReflectionUtils 工具类,离大佬又近一步

ReflectionUtils是Spring框架中的反射工具类,它提供了一系列静态方法,可以方便地进行类、对象、方法、字段等反射操作。

  1. shallowCopyFieldState(final Object src, final Object dest)

    将源对象的属性值浅拷贝到目标对象中。

    该方法会遍历源对象的所有可读属性,并将其值拷贝到目标对象的对应属性中。

    拷贝的方式是通过直接赋值来实现的,因此是浅拷贝,即拷贝的是属性的引用而不是属性的副本。

    Person source = new Person();
    source.setName("John");
    source.setAge(25);
    PersonVO target = new PersonVO();
    // 浅拷贝
    ReflectionUtils.shallowCopyFieldState(source, target);        
    System.out.println("Name: " + target.getName());
    System.out.println("Age: " + target.getAge());

    运行结果:

    Name: John
    Age: 25
  2. handleReflectionException(Exception ex)

    用于处理反射操作中可能抛出的异常。

    它接受一个Exception类型的参数ex,表示要处理的异常。

    Person example = new Person();
    try {
        Method method = Person.class.getMethod("nonExistingMethod");
        ReflectionUtils.invokeMethod(method, example);
    } catch (Exception ex) {
        // 处理反射操作中的异常
        ReflectionUtils.handleReflectionException(ex);
    }

    运行结果:

    Exception in thread "main" java.lang.IllegalStateException: Method not found: com.cloudfish.test.Person.nonExistingMethod()
        at org.springframework.util.ReflectionUtils.handleReflectionException(ReflectionUtils.java:109)
        at com.cloudfish.test.ReflectionUtilsTest.main(ReflectionUtilsTest.java:26)

    在示例中,我们调用了一个不存在的方法,固抛异常了。

  3. handleInvocationTargetException(InvocationTargetException ex)

    处理给定的调用目标异常,InvocationTargetException是Java反射中的一个异常类,它表示在调用方法时发生了异常。

    通常情况下,我们可以使用getCause()方法获取原始的异常对象。

  4. rethrowRuntimeException(Throwable ex)

    重新抛出一个运行时异常。

  5. rethrowException(Throwable ex)

    重新抛出一个异常,重新抛出的异常分为三种类型:

    运行时异常RuntimeException、Error、UndeclaredThrowableException。

  6. ReflectionUtils.accessibleConstructor(Classclazz, Class<?>... parameterTypes)

    用于获取指定类的可访问构造函数。

    try {
        Constructor<Person> constructor = ReflectionUtils.accessibleConstructor(Person.class, String.class, int.class);
        Person example = constructor.newInstance("John Doe", 25);
        System.out.println("Name: " + example.getName());
        System.out.println("Age: " + example.getAge());
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    运行结果:

    Name: John Doe
    Age: 25
  7. Method findMethod(Class<?> clazz, String name)

    获取指定类的指定方法。

    Method getNameMethod = ReflectionUtils.findMethod(Person.class, "getName");
    System.out.println("getName method: " + getNameMethod);

    运行结果:

    setName method: public java.lang.String com.cloudfish.test.Person.getName()

    注意:该方法只能获取没有参数的方法。

  8. findMethod(Class clazz, String name, @Nullable Class... paramTypes)

    获取指定类的指定方法,该方法还有一个或多个参数类型。

    Method setNameMethod = ReflectionUtils.findMethod(Person.class, "setName", String.class);
    System.out.println("setName method: " + setNameMethod);

    运行结果:

    setName method: public void com.cloudfish.test.Person.setName(java.lang.String)
  9. invokeMethod(Method method, @Nullable Object target)

    用于调用指定方法,并传入目标对象(可选)。

    Method setNameMethod = ReflectionUtils.findMethod(Person.class, "setName", String.class);
    System.out.println("setName method: " + setNameMethod);        
    
    Person example = new Person();
    // 设置访问权限才可访问
    setNameMethod.setAccessible(true);
    ReflectionUtils.invokeMethod(setNameMethod, example, "eeefdfdfd");          
    System.out.println(example.getName());

    运行结果:

    setName method: public void com.cloudfish.test.Person.setName(java.lang.String)
    eeefdfdfd
  10. declaresException(Method method, Class<?> exceptionType)

    用于检查指定方法是否声明了指定的异常类型。

    Method method = ReflectionUtils.findMethod(Person.class, "getName");
    boolean declaresIOException = ReflectionUtils.declaresException(method, IOException.class);
    System.out.println("Declares IOException: " + declaresIOException);
    
    boolean declaresNullPointerException = ReflectionUtils.declaresException(method, NullPointerException.class);
    System.out.println("Declares NullPointerException: " + declaresNullPointerException);

    运行结果:

    Declares IOException: false
    Declares NullPointerException: false
  11. doWithLocalMethods(Class<?> clazz, MethodCallback mc)

    用于迭代指定类的所有本地方法,并对每个方法执行回调操作。

    ReflectionUtils.doWithLocalMethods(Person.class, new PersonCallback());

    回调类:

    // 需要实现MethodCallback 方法
    class PersonCallback implements MethodCallback {
        @Override
        public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
            System.out.println("Method name: " + method.getName());
        }
    }

    运行结果:

    Method name: hashCode
    Method name: getAddress
    Method name: getName
    Method name: setName
    Method name: setAddress
    Method name: getAge
    Method name: setAge

    打印了person中所有的方法。

  12. doWithMethods(Class<?> clazz, MethodCallback mc)

    用于迭代指定类的所有方法,并对每个方法执行回调操作。

    ReflectionUtils.doWithMethods(Person.class, new PersonCallback());

    运行结果:

    Method name: hashCode
    Method name: getAddress
    Method name: getName
    Method name: setName
    Method name: setAge
    Method name: getAge
    Method name: setAddress
    Method name: finalize
    Method name: wait
    Method name: wait
    Method name: wait
    Method name: equals
    Method name: toString
    Method name: hashCode
    Method name: getClass
    Method name: clone
    Method name: notify
    Method name: notifyAll
    Method name: registerNatives
  13. doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf)

    用于迭代指定类的所有方法,并对每个方法执行回调操作。

    ReflectionUtils.doWithMethods(Person.class, new PersonCallback(), new PersonMethodFilter());
    
    // 需要实现MethodFilter接口
    class PersonMethodFilter implements MethodFilter {
    
        @Override
        public boolean matches(Method method) {
            return Modifier.isPublic(method.getModifiers());
        }    
    }

    运行结果:

    Method name: hashCode
    Method name: getAddress
    Method name: getName
    Method name: setName
    Method name: setAge
    Method name: setAddress
    Method name: getAge
    Method name: wait
    Method name: wait
    Method name: wait
    Method name: equals
    Method name: toString
    Method name: hashCode
    Method name: getClass
    Method name: notify
    Method name: notifyAll
  14. getAllDeclaredMethods(Class<?> leafClass)

    用于获取指定类及其所有父类中声明的所有方法。

    Class<?> leafClass = PersonVO.class;
    Method[] methods = ReflectionUtils.getAllDeclaredMethods(leafClass);
    for (Method method : methods) {
       System.out.println("Method name: " + method.getName());
    }

    运行结果:

    Method name: getHobbies
    Method name: setHobbies
    Method name: hashCode
    Method name: getAddress
    Method name: getName
    Method name: setName
    Method name: setAddress
    Method name: getAge
    Method name: setAge
    Method name: finalize
    Method name: wait
    Method name: wait
    Method name: wait
    Method name: equals
    Method name: toString
    Method name: hashCode
    Method name: getClass
    Method name: clone
    Method name: notify
    Method name: notifyAll
    Method name: registerNatives
  15. getUniqueDeclaredMethods(Class<?> leafClass)

    用于获取指定类及其所有父类中声明的所有唯一方法。

    Class<?> leafClass = PersonVO.class;
    Method[] methods = ReflectionUtils.getUniqueDeclaredMethods(leafClass);
    for (Method method : methods) {
        System.out.println("Method name: " + method.getName());
    }

    运行结果:

    Method name: getHobbies
    Method name: setHobbies
    Method name: hashCode
    Method name: getAddress
    Method name: getName
    Method name: setName
    Method name: setAge
    Method name: getAge
    Method name: setAddress
    Method name: finalize
    Method name: wait
    Method name: wait
    Method name: wait
    Method name: equals
    Method name: toString
    Method name: getClass
    Method name: clone
    Method name: notify
    Method name: notifyAll
    Method name: registerNatives
  16. isEqualsMethod(@Nullable Method method)

    用于判断给定的方法是否是equals方法。

    try {
        Class<?> clazz = PersonVO.class;
        Method method = clazz.getMethod("equals", Object.class);
        boolean isEquals = ReflectionUtils.isEqualsMethod(method);
        System.out.println("Is equals method: " + isEquals);
    } catch (NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
    }

    运行结果:

    Is equals method: true
  17. isHashCodeMethod(@Nullable Method method)

    用于判断给定的方法是否是hashCode方法。

  18. isToStringMethod(@Nullable Method method)

    用于判断给定的方法是否是toString方法。

  19. isObjectMethod(@Nullable Method method)

    用于判断给定的方法是否是Object类中的方法。

    try {
        Class<?> clazz = PersonVO.class;
        Method method = clazz.getMethod("getName");    
        boolean isObjectMethod = ReflectionUtils.isObjectMethod(method);
        System.out.println("Is Object method: " + isObjectMethod);
    } catch (NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
    }

    运行结果:

    Is Object method: false
  20. isCglibRenamedMethod(Method renamedMethod)

    用于判断给定的方法是否是Cglib的类中的renamed方法。

  21. findField(Class<?> clazz, String name)

    用于在给定的类及其父类中查找指定名称的字段。

    Class<?> clazz = PersonVO.class;
    Field field = ReflectionUtils.findField(clazz, "name");
    System.out.println("Field name: " + field.getName());

    运行结果:

    Field name: name
  22. findField(Class clazz, @Nullable String name, @Nullable Class type)

    用于在给定的类及其父类中查找指定名称、类型的字段。

  23. setField(Field field, @Nullable Object target, @Nullable Object value)

    用于设置指定字段的值。

    try {
        Person myObject = new Person();
        Field field = Person.class.getDeclaredField("name");
        // 设置为可以访问
        field.setAccessible(true);
        ReflectionUtils.setField(field, myObject, "Hello, World!");
        System.out.println("Field value: " + myObject.getName());
    } catch (NoSuchFieldException | SecurityException e) {
        e.printStackTrace();
    }

    运行结果:

    Field value: Hello, World!
  24. getField(Field field, @Nullable Object target)

    用于获取指定字段的值。

    try {
        Person myObject = new Person("aaaa",10);
        Field field = Person.class.getDeclaredField("name");
        field.setAccessible(true);
        Object value = ReflectionUtils.getField(field, myObject);
        System.out.println("Field value: " + value);
    } catch (NoSuchFieldException | SecurityException e) {
        e.printStackTrace();
    }

    运行结果:

    Field value: aaaa
  25. doWithLocalFields(Class<?> clazz, FieldCallback fc)

    用于对指定类的本地字段(即不包括父类的字段)进行操作。

    Class<?> clazz = PersonVO.class;
    MyFieldCallback fieldCallback = new MyFieldCallback();
    ReflectionUtils.doWithLocalFields(clazz, fieldCallback);
    //FieldCallback 类
    class MyFieldCallback implements FieldCallback {
      @Override
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        System.out.println("Field name: " + field.getName());
        System.out.println("Field type: " + field.getType());
      }
    }

    运行结果:

    Field name: hobbies
    Field type: interface java.util.List
  26. doWithFields(Class<?> clazz, FieldCallback fc)

    用于对指定类的字段(包括父类的字段)进行操作。

    Class<?> clazz = PersonVO.class;
    MyFieldCallback fieldCallback = new MyFieldCallback();
    ReflectionUtils.doWithFields(clazz, fieldCallback);

    运行结果:

    Field name: hobbies
    Field type: interface java.util.List
    Field name: name
    Field type: class java.lang.String
    Field name: age
    Field type: int
    Field name: address
    Field type: class java.lang.String
  27. doWithFields(Class<?> clazz, FieldCallback fc, @Nullable FieldFilter ff)

    用于对指定类的符合条件的字段进行操作。

    Person myObject = new Person();
    // 使用doWithFields方法对字段进行操作
    ReflectionUtils.doWithFields(Person.class, new FieldCallback() {
        @Override
        public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
            // 在这里可以对每个字段进行自定义操作
            field.setAccessible(true); // 设置字段可访问,因为字段是私有的
            Object value = field.get(myObject); // 获取字段的值
            System.out.println("Field name: " + field.getName());
            System.out.println("Field type: " + field.getType());
            System.out.println("Field value: " + value);
        }
    }, new FieldFilter() {
        @Override
        public boolean matches(Field field) {
            // 在这里可以定义过滤条件,只处理满足条件的字段
            return field.getType() == String.class; // 只处理类型为String的字段
        }
    });

    使用匿名内部类实现了FieldCallback接口,并在doWith方法中定义了对每个字段的操作。

    在doWith方法中,我们首先将字段设置为可访问状态,然后使用field.get(myObject)方法获取字段的值,并打印字段的名称、类型和值。

    同时,我们还使用匿名内部类实现了FieldFilter接口,并在matches方法中定义了过滤条件。

    在这个示例中,我们只处理类型为String的字段。

    运行结果:

    Field name: name
    Field type: class java.lang.String
    Field value: null
    Field name: address
    Field type: class java.lang.String
    Field value: null
  28. isPublicStaticFinal(Field field)

    用于判断一个字段是否是public、static和final修饰的。

    Field[] fields = Person.class.getDeclaredFields();
    for (Field field : fields) {
        if (ReflectionUtils.isPublicStaticFinal(field)) {
            System.out.println(field.getName() + " is public, static, and final.");
        }
    }

    由于在person对象中,并没有这样的字段,所以没有打印结果。

最后总结一下,ReflectionUtils工具类的作用:

  • 获取类的信息:ReflectionUtils可以通过类的全限定名获取对应的Class对象,进而获取类的各种信息,如类名、包名、父类、接口等。

  • 创建对象:ReflectionUtils可以通过Class对象创建实例,即通过反射实现动态创建对象的功能。

  • 调用方法:ReflectionUtils可以通过Method对象调用类的方法,包括无参方法和有参方法,可以通过方法名和参数类型来定位方法。

  • 访问字段:ReflectionUtils可以通过Field对象访问类的字段,包括获取字段值和设置字段值。

  • 调用构造方法:ReflectionUtils可以通过Constructor对象调用类的构造方法,包括无参构造方法和有参构造方法

推荐阅读:
被 GPT-4 Plus 账号价格劝退了!
世界的真实格局分析,地球人类社会底层运行原理
不是你需要中台,而是一名合格的架构师(附各大厂中台建设PPT)

企业IT技术架构规划方案

论数字化转型——转什么,如何转?

华为干部与人才发展手册(附PPT)
【中台实践】华为大数据中台架构分享.pdf

华为的数字化转型方法论

华为如何实施数字化转型(附PPT)
华为大数据解决方案(PPT)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值