玩转 ReflectionUtils 工具类,离大佬又近一步
ReflectionUtils是Spring框架中的反射工具类,它提供了一系列静态方法,可以方便地进行类、对象、方法、字段等反射操作。
- shallowCopyFieldState(final Object src, final Object dest)将源对象的属性值浅拷贝到目标对象中。该方法会遍历源对象的所有可读属性,并将其值拷贝到目标对象的对应属性中。拷贝的方式是通过直接赋值来实现的,因此是浅拷贝,即拷贝的是属性的引用而不是属性的副本。Person source =newPerson();source.setName("John");source.setAge(25);PersonVO target =newPersonVO();
// 浅拷贝ReflectionUtils.shallowCopyFieldState(source, target);System.out.println("Name: "+ target.getName());System.out.println("Age: "+ target.getAge());运行结果:Name: JohnAge: 25 - handleReflectionException(Exception ex)用于处理反射操作中可能抛出的异常。它接受一个Exception类型的参数ex,表示要处理的异常。Person example =newPerson();
try{Method method = Person.class.getMethod("nonExistingMethod");ReflectionUtils.invokeMethod(method, example);}catch(Exception ex) {
// 处理反射操作中的异常ReflectionUtils.handleReflectionException(ex);}运行结果:Exceptioninthread"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)在示例中,我们调用了一个不存在的方法,固抛异常了。 - handleInvocationTargetException(InvocationTargetException ex)处理给定的调用目标异常,InvocationTargetException是Java反射中的一个异常类,它表示在调用方法时发生了异常。通常情况下,我们可以使用getCause()方法获取原始的异常对象。
- rethrowRuntimeException(Throwable ex)重新抛出一个运行时异常。
- rethrowException(Throwable ex)重新抛出一个异常,重新抛出的异常分为三种类型:运行时异常RuntimeException、Error、UndeclaredThrowableException。
- ReflectionUtils.accessibleConstructor(Class
clazz, 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 DoeAge: 25 - 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()注意:该方法只能获取没有参数的方法。
- 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)
- invokeMethod(Method method, @Nullable Object target)用于调用指定方法,并传入目标对象(可选)。Method setNameMethod = ReflectionUtils.findMethod(Person.class, "setName", String.class);System.out.println("setName method: "+ setNameMethod);Person example =newPerson();
// 设置访问权限才可访问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 - declaresException(Method method, Class<?> exceptionType)用于检查指定方法是否声明了指定的异常类型。Method method = ReflectionUtils.findMethod(Person.class, "getName");
booleandeclaresIOException = ReflectionUtils.declaresException(method, IOException.class);System.out.println("Declares IOException: "+ declaresIOException);
booleandeclaresNullPointerException = ReflectionUtils.declaresException(method, NullPointerException.class);System.out.println("Declares NullPointerException: "+ declaresNullPointerException);运行结果:Declares IOException:falseDeclares NullPointerException:false - doWithLocalMethods(Class<?> clazz, MethodCallback mc)用于迭代指定类的所有本地方法,并对每个方法执行回调操作。ReflectionUtils.doWithLocalMethods(Person.class, newPersonCallback());回调类:
// 需要实现MethodCallback 方法
classPersonCallbackimplementsMethodCallback{
@Override
publicvoiddoWith(Method method)throws IllegalArgumentException, IllegalAccessException{System.out.println("Method name: "+ method.getName());}}运行结果:Method name: hashCodeMethod name: getAddressMethod name: getNameMethod name: setNameMethod name: setAddressMethod name: getAgeMethod name: setAge打印了person中所有的方法。 - doWithMethods(Class<?> clazz, MethodCallback mc)用于迭代指定类的所有方法,并对每个方法执行回调操作。ReflectionUtils.doWithMethods(Person.class, newPersonCallback());运行结果:Method name: hashCodeMethod name: getAddressMethod name: getNameMethod name: setNameMethod name: setAgeMethod name: getAgeMethod name: setAddressMethod name: finalizeMethod name:waitMethod name:waitMethod name:waitMethod name: equalsMethod name: toStringMethod name: hashCodeMethod name: getClassMethod name:cloneMethod name: notifyMethod name: notifyAllMethod name: registerNatives
- doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf)用于迭代指定类的所有方法,并对每个方法执行回调操作。ReflectionUtils.doWithMethods(Person.class, newPersonCallback(), newPersonMethodFilter());
// 需要实现MethodFilter接口
classPersonMethodFilterimplementsMethodFilter{
@Override
publicbooleanmatches(Method method){
returnModifier.isPublic(method.getModifiers());}}运行结果:Method name: hashCodeMethod name: getAddressMethod name: getNameMethod name: setNameMethod name: setAgeMethod name: setAddressMethod name: getAgeMethod name:waitMethod name:waitMethod name:waitMethod name: equalsMethod name: toStringMethod name: hashCodeMethod name: getClassMethod name: notifyMethod name: notifyAll - 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: getHobbiesMethod name: setHobbiesMethod name: hashCodeMethod name: getAddressMethod name: getNameMethod name: setNameMethod name: setAddressMethod name: getAgeMethod name: setAgeMethod name: finalizeMethod name:waitMethod name:waitMethod name:waitMethod name: equalsMethod name: toStringMethod name: hashCodeMethod name: getClassMethod name:cloneMethod name: notifyMethod name: notifyAllMethod name: registerNatives - 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: getHobbiesMethod name: setHobbiesMethod name: hashCodeMethod name: getAddressMethod name: getNameMethod name: setNameMethod name: setAgeMethod name: getAgeMethod name: setAddressMethod name: finalizeMethod name:waitMethod name:waitMethod name:waitMethod name: equalsMethod name: toStringMethod name: getClassMethod name:cloneMethod name: notifyMethod name: notifyAllMethod name: registerNatives - isEqualsMethod(@Nullable Method method)用于判断给定的方法是否是equals方法。
try
{Class<?> clazz = PersonVO.class;Method method = clazz.getMethod("equals", Object.class);
booleanisEquals = ReflectionUtils.isEqualsMethod(method);System.out.println("Is equals method: "+ isEquals);}catch(NoSuchMethodException | SecurityException e) {e.printStackTrace();}运行结果:Is equals method:true - isHashCodeMethod(@Nullable Method method)用于判断给定的方法是否是hashCode方法。
- isToStringMethod(@Nullable Method method)用于判断给定的方法是否是toString方法。
- isObjectMethod(@Nullable Method method)用于判断给定的方法是否是Object类中的方法。
try
{Class<?> clazz = PersonVO.class;Method method = clazz.getMethod("getName");
booleanisObjectMethod = ReflectionUtils.isObjectMethod(method);System.out.println("Is Object method: "+ isObjectMethod);}catch(NoSuchMethodException | SecurityException e) {e.printStackTrace();}运行结果:Is Object method:false - isCglibRenamedMethod(Method renamedMethod)用于判断给定的方法是否是Cglib的类中的renamed方法。
- 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
- findField(Class clazz, @Nullable String name, @Nullable Class type)用于在给定的类及其父类中查找指定名称、类型的字段。
- setField(Field field, @Nullable Object target, @Nullable Object value)用于设置指定字段的值。
try
{Person myObject =newPerson();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! - getField(Field field, @Nullable Object target)用于获取指定字段的值。
try
{Person myObject =newPerson("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 - doWithLocalFields(Class<?> clazz, FieldCallback fc)用于对指定类的本地字段(即不包括父类的字段)进行操作。
- 微信搜索公众号:架构师指南,回复:架构师 领取资料 。Class<?> clazz = PersonVO.class;MyFieldCallback fieldCallback =newMyFieldCallback();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: hobbiesFieldtype: interface java.util.List - doWithFields(Class<?> clazz, FieldCallback fc)用于对指定类的字段(包括父类的字段)进行操作。Class<?> clazz = PersonVO.class;MyFieldCallback fieldCallback =newMyFieldCallback();ReflectionUtils.doWithFields(clazz, fieldCallback);运行结果:Field name: hobbiesFieldtype: interface java.util.ListField name: nameFieldtype: class java.lang.StringField name: ageFieldtype: intField name: addressFieldtype: class java.lang.String
- doWithFields(Class<?> clazz, FieldCallback fc, @Nullable FieldFilter ff)用于对指定类的符合条件的字段进行操作。Person myObject =newPerson();
// 使用doWithFields方法对字段进行操作ReflectionUtils.doWithFields(Person.class, newFieldCallback(){
@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);}},newFieldFilter() {
@Override
publicbooleanmatches(Field field){
// 在这里可以定义过滤条件,只处理满足条件的字段
returnfield.getType() == String.class;// 只处理类型为String的字段}});使用匿名内部类实现了FieldCallback接口,并在doWith方法中定义了对每个字段的操作。在doWith方法中,我们首先将字段设置为可访问状态,然后使用field.get(myObject)方法获取字段的值,并打印字段的名称、类型和值。同时,我们还使用匿名内部类实现了FieldFilter接口,并在matches方法中定义了过滤条件。在这个示例中,我们只处理类型为String的字段。运行结果:Field name: nameFieldtype: class java.lang.StringField value: nullField name: addressFieldtype: class java.lang.StringField value: null - 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对象调用类的构造方法,包括无参构造方法和有参构造方法
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。