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
    .classString.classint.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
    .classnewPersonCallback())
    ;

    回调类:
    // 需要实现MethodCallback 方法
    classPersonCallbackimplementsMethodCallback
    {

    @Override
    publicvoiddoWith(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
    .classnewPersonCallback())
    ;

    运行结果:
    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
    .classnewPersonCallback(), newPersonMethodFilter())
    ;


    // 需要实现MethodFilter接口
    classPersonMethodFilterimplementsMethodFilter
    {


    @Override
    publicbooleanmatches(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)
    用于对指定类的本地字段(即不包括父类的字段)进行操作。
  26. 微信搜索公众号:架构师指南,回复:架构师 领取资料 。
    Class<?> clazz = PersonVO
    .class
    ;

    MyFieldCallback fieldCallback = 
    new
     MyFieldCallback();

    ReflectionUtils.doWithLocalFields(clazz, fieldCallback);

    //FieldCallback 类
    classMyFieldCallbackimplementsFieldCallback
    {

    @Override
    publicvoiddoWith(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

  27. 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

  28. doWithFields(Class<?> clazz, FieldCallback fc, @Nullable FieldFilter ff)
    用于对指定类的符合条件的字段进行操作。
    Person myObject = 
    new
     Person();

    // 使用doWithFields方法对字段进行操作
    ReflectionUtils.doWithFields(Person
    .classnewFieldCallback() 
    {

    @Override
    publicvoiddoWith(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
    publicbooleanmatches(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

  29. 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对象调用类的构造方法,包括无参构造方法和有参构造方法
继续阅读
阅读原文